You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by GitBox <gi...@apache.org> on 2018/01/08 18:49:19 UTC

[GitHub] rhtyd closed pull request #2350: Cloudstack 10170 - fixes resource tags security bugs and adds account tags support

rhtyd closed pull request #2350: Cloudstack 10170 - fixes resource tags security bugs and adds account tags support
URL: https://github.com/apache/cloudstack/pull/2350
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java
index 067cb973e2f..0bd5d734e30 100644
--- a/api/src/com/cloud/server/ResourceTag.java
+++ b/api/src/com/cloud/server/ResourceTag.java
@@ -38,6 +38,7 @@
         SecurityGroupRule(true, false),
         PublicIpAddress(true, true),
         Project(true, false),
+        Account(true, false),
         Vpc(true, true),
         NetworkACL(true, true),
         StaticRoute(true, false),
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index 412ca5bead7..1632da95f95 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -3804,6 +3804,9 @@ public boolean releasePublicIpRange(final ReleasePublicIpRangeCmd cmd) {
     @DB
     public boolean releasePublicIpRange(final long vlanDbId, final long userId, final Account caller) {
         VlanVO vlan = _vlanDao.findById(vlanDbId);
+        if(vlan == null) {
+            s_logger.warn("VLAN information for Account '" + caller + "', User '" + userId + "' VLAN '" + vlanDbId + "' is null. This is NPE situation.");
+        }
 
         // Verify range is dedicated
         boolean isAccountSpecific = false;
diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java
index 9373a08fcf8..9803ce753a3 100644
--- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java
+++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java
@@ -16,28 +16,13 @@
 // under the License.
 package com.cloud.tags;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-
-import com.cloud.api.query.dao.ResourceTagJoinDao;
 import com.cloud.dc.DataCenterVO;
 import com.cloud.domain.PartOf;
 import com.cloud.event.ActionEvent;
 import com.cloud.event.EventTypes;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.PermissionDeniedException;
+import com.cloud.offerings.NetworkOfferingVO;
 import com.cloud.network.LBHealthCheckPolicyVO;
 import com.cloud.network.as.AutoScaleVmGroupVO;
 import com.cloud.network.as.AutoScaleVmProfileVO;
@@ -58,7 +43,6 @@
 import com.cloud.network.vpc.StaticRouteVO;
 import com.cloud.network.vpc.VpcOfferingVO;
 import com.cloud.network.vpc.VpcVO;
-import com.cloud.offerings.NetworkOfferingVO;
 import com.cloud.projects.ProjectVO;
 import com.cloud.server.ResourceTag;
 import com.cloud.server.ResourceTag.ResourceObjectType;
@@ -72,6 +56,7 @@
 import com.cloud.tags.dao.ResourceTagDao;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
 import com.cloud.user.DomainManager;
 import com.cloud.user.OwnedBy;
 import com.cloud.user.UserVO;
@@ -89,11 +74,28 @@
 import com.cloud.vm.NicVO;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.snapshot.VMSnapshotVO;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import org.apache.commons.collections.MapUtils;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
 
 public class TaggedResourceManagerImpl extends ManagerBase implements TaggedResourceService {
     public static final Logger s_logger = Logger.getLogger(TaggedResourceManagerImpl.class);
 
-    private static final Map<ResourceObjectType, Class<?>> s_typeMap = new HashMap<ResourceObjectType, Class<?>>();
+    private static final Map<ResourceObjectType, Class<?>> s_typeMap = new HashMap<>();
     static {
         s_typeMap.put(ResourceObjectType.UserVm, UserVmVO.class);
         s_typeMap.put(ResourceObjectType.Volume, VolumeVO.class);
@@ -108,6 +110,7 @@
         s_typeMap.put(ResourceObjectType.SecurityGroupRule, SecurityGroupRuleVO.class);
         s_typeMap.put(ResourceObjectType.PublicIpAddress, IPAddressVO.class);
         s_typeMap.put(ResourceObjectType.Project, ProjectVO.class);
+        s_typeMap.put(ResourceObjectType.Account, AccountVO.class);
         s_typeMap.put(ResourceObjectType.Vpc, VpcVO.class);
         s_typeMap.put(ResourceObjectType.Nic, NicVO.class);
         s_typeMap.put(ResourceObjectType.NetworkACL, NetworkACLItemVO.class);
@@ -140,8 +143,6 @@
     @Inject
     ResourceTagDao _resourceTagDao;
     @Inject
-    ResourceTagJoinDao _resourceTagJoinDao;
-    @Inject
     DomainManager _domainMgr;
     @Inject
     AccountDao _accountDao;
@@ -194,6 +195,12 @@ public long getResourceId(String resourceId, ResourceObjectType resourceType) {
             domainId = ((SecurityGroupVO)SecurityGroup).getDomainId();
         }
 
+        if (resourceType == ResourceObjectType.Account) {
+            AccountVO account = (AccountVO)entity;
+            accountId = account.getId();
+            domainId = account.getDomainId();
+        }
+
         // if the resource type is network acl, get the accountId and domainId from VPC following: NetworkACLItem -> NetworkACL -> VPC
         if (resourceType == ResourceObjectType.NetworkACL) {
             NetworkACLItemVO aclItem = (NetworkACLItemVO)entity;
@@ -223,7 +230,23 @@ public long getResourceId(String resourceId, ResourceObjectType resourceType) {
         if ((domainId == null) || ((accountId != null) && (domainId.longValue() == -1))) {
             domainId = _accountDao.getDomainIdForGivenAccountId(accountId);
         }
-        return new Pair<Long, Long>(accountId, domainId);
+        return new Pair<>(accountId, domainId);
+    }
+
+    private void checkResourceAccessible(Long accountId, Long domainId, String exceptionMessage) {
+        Account caller = CallContext.current().getCallingAccount();
+        if (Objects.equals(domainId, -1))
+        {
+            throw new CloudRuntimeException("Invalid DomainId: -1");
+        }
+        if (accountId != null) {
+            _accountMgr.checkAccess(caller, null, false, _accountMgr.getAccount(accountId));
+        } else if (domainId != null && !_accountMgr.isNormalUser(caller.getId())) {
+            //check permissions;
+            _accountMgr.checkAccess(caller, _domainMgr.getDomain(domainId));
+        } else {
+            throw new PermissionDeniedException(exceptionMessage);
+        }
     }
 
     @Override
@@ -237,13 +260,29 @@ public ResourceObjectType getResourceType(String resourceTypeStr) {
         throw new InvalidParameterValueException("Invalid resource type " + resourceTypeStr);
     }
 
+    @Override
+    public String getUuid(String resourceId, ResourceObjectType resourceType) {
+        if (!StringUtils.isNumeric(resourceId)) {
+            return resourceId;
+        }
+
+        Class<?> clazz = s_typeMap.get(resourceType);
+
+        Object entity = _entityMgr.findById(clazz, resourceId);
+        if (entity != null && entity instanceof Identity) {
+            return ((Identity)entity).getUuid();
+        }
+
+        return resourceId;
+    }
+
     @Override
     @DB
     @ActionEvent(eventType = EventTypes.EVENT_TAGS_CREATE, eventDescription = "creating resource tags")
     public List<ResourceTag> createTags(final List<String> resourceIds, final ResourceObjectType resourceType, final Map<String, String> tags, final String customer) {
         final Account caller = CallContext.current().getCallingAccount();
 
-        final List<ResourceTag> resourceTags = new ArrayList<ResourceTag>(tags.size());
+        final List<ResourceTag> resourceTags = new ArrayList<>(tags.size());
 
         Transaction.execute(new TransactionCallbackNoReturn() {
             @Override
@@ -261,17 +300,8 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
                         Long domainId = accountDomainPair.second();
                         Long accountId = accountDomainPair.first();
 
-                        if ((domainId != null) && (domainId == -1)) {
-                            throw new CloudRuntimeException("Invalid DomainId : -1");
-                        }
-                        if (accountId != null) {
-                            _accountMgr.checkAccess(caller, null, false, _accountMgr.getAccount(accountId));
-                        } else if (domainId != null && !_accountMgr.isNormalUser(caller.getId())) {
-                            //check permissions;
-                            _accountMgr.checkAccess(caller, _domainMgr.getDomain(domainId));
-                        } else {
-                            throw new PermissionDeniedException("Account " + caller + " doesn't have permissions to create tags" + " for resource " + key);
-                        }
+                        checkResourceAccessible(accountId, domainId, "Account '" + caller +
+                                "' doesn't have permissions to create tags" + " for resource '" + id + "(" + key + ")'.");
 
                         String value = tags.get(key);
 
@@ -290,20 +320,16 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
         return resourceTags;
     }
 
-    @Override
-    public String getUuid(String resourceId, ResourceObjectType resourceType) {
-        if (!StringUtils.isNumeric(resourceId)) {
-            return resourceId;
-        }
-
-        Class<?> clazz = s_typeMap.get(resourceType);
-
-        Object entity = _entityMgr.findById(clazz, resourceId);
-        if (entity != null && entity instanceof Identity) {
-            return ((Identity)entity).getUuid();
-        }
+    private List<? extends ResourceTag> searchResourceTags(List<String> resourceIds, ResourceObjectType resourceType) {
+        List<String> resourceUuids = resourceIds.stream().map(resourceId -> getUuid(resourceId, resourceType)).collect(Collectors.toList());
+        SearchBuilder<ResourceTagVO> sb = _resourceTagDao.createSearchBuilder();
+        sb.and("resourceUuid", sb.entity().getResourceUuid(), SearchCriteria.Op.IN);
+        sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ);
 
-        return resourceId;
+        SearchCriteria<ResourceTagVO> sc = sb.create();
+        sc.setParameters("resourceUuid", resourceUuids.toArray());
+        sc.setParameters("resourceType", resourceType);
+        return _resourceTagDao.search(sc, null);
     }
 
     @Override
@@ -311,62 +337,60 @@ public String getUuid(String resourceId, ResourceObjectType resourceType) {
     @ActionEvent(eventType = EventTypes.EVENT_TAGS_DELETE, eventDescription = "deleting resource tags")
     public boolean deleteTags(List<String> resourceIds, ResourceObjectType resourceType, Map<String, String> tags) {
         Account caller = CallContext.current().getCallingAccount();
-
-        SearchBuilder<ResourceTagVO> sb = _resourceTagDao.createSearchBuilder();
-        sb.and().op("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.IN);
-        sb.or("resourceUuid", sb.entity().getResourceUuid(), SearchCriteria.Op.IN);
-        sb.cp();
-        sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ);
-
-        SearchCriteria<ResourceTagVO> sc = sb.create();
-        sc.setParameters("resourceId", resourceIds.toArray());
-        sc.setParameters("resourceUuid", resourceIds.toArray());
-        sc.setParameters("resourceType", resourceType);
-
-        List<? extends ResourceTag> resourceTags = _resourceTagDao.search(sc, null);
-        ;
-        final List<ResourceTag> tagsToRemove = new ArrayList<ResourceTag>();
+        if(s_logger.isDebugEnabled()) {
+            s_logger.debug("ResourceIds to Find " + String.join(", ", resourceIds));
+        }
+        List<? extends ResourceTag> resourceTags = searchResourceTags(resourceIds, resourceType);
+        final List<ResourceTag> tagsToDelete = new ArrayList<>();
 
         // Finalize which tags should be removed
         for (ResourceTag resourceTag : resourceTags) {
             //1) validate the permissions
+            if(s_logger.isDebugEnabled()) {
+                s_logger.debug("Resource Tag Id: " + resourceTag.getResourceId());
+                s_logger.debug("Resource Tag AccountId: " + resourceTag.getAccountId());
+            }
             Account owner = _accountMgr.getAccount(resourceTag.getAccountId());
+            if(s_logger.isDebugEnabled()) {
+                s_logger.debug("Resource Owner: " + owner);
+            }
             _accountMgr.checkAccess(caller, null, false, owner);
             //2) Only remove tag if it matches key value pairs
-            if (tags != null && !tags.isEmpty()) {
+            if (MapUtils.isEmpty(tags)) {
+                tagsToDelete.add(resourceTag);
+            } else {
                 for (String key : tags.keySet()) {
-                    boolean canBeRemoved = false;
+                    boolean deleteTag = false;
                     if (resourceTag.getKey().equalsIgnoreCase(key)) {
                         String value = tags.get(key);
                         if (value != null) {
                             if (resourceTag.getValue().equalsIgnoreCase(value)) {
-                                canBeRemoved = true;
+                                deleteTag = true;
                             }
                         } else {
-                            canBeRemoved = true;
+                            deleteTag = true;
                         }
-                        if (canBeRemoved) {
-                            tagsToRemove.add(resourceTag);
+                        if (deleteTag) {
+                            tagsToDelete.add(resourceTag);
                             break;
                         }
                     }
                 }
-            } else {
-                tagsToRemove.add(resourceTag);
             }
         }
 
-        if (tagsToRemove.isEmpty()) {
-            throw new InvalidParameterValueException("Unable to find tags by parameters specified");
+        if (tagsToDelete.isEmpty()) {
+            throw new InvalidParameterValueException("Unable to find any tags which conform to specified delete parameters.");
         }
 
         //Remove the tags
         Transaction.execute(new TransactionCallbackNoReturn() {
             @Override
             public void doInTransactionWithoutResult(TransactionStatus status) {
-                for (ResourceTag tagToRemove : tagsToRemove) {
+                for (ResourceTag tagToRemove : tagsToDelete) {
                     _resourceTagDao.remove(tagToRemove.getId());
-                    s_logger.debug("Removed the tag " + tagToRemove);
+                    s_logger.debug("Removed the tag '" + tagToRemove + "' for resources (" +
+                            String.join(", ", resourceIds) + ")");
                 }
             }
         });
@@ -375,7 +399,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
     }
 
     @Override
-    public List<? extends ResourceTag> listByResourceTypeAndId(ResourceObjectType type, long resourceId) {
-        return _resourceTagDao.listBy(resourceId, type);
+    public List<? extends ResourceTag> listByResourceTypeAndId(ResourceObjectType resourceType, long resourceId) {
+        return _resourceTagDao.listBy(resourceId, resourceType);
     }
 }
diff --git a/setup/dev/advanced.cfg b/setup/dev/advanced.cfg
index d5762c39bce..d458b015e75 100644
--- a/setup/dev/advanced.cfg
+++ b/setup/dev/advanced.cfg
@@ -154,7 +154,7 @@
     },
     "logger":
         {
-            "LogFolderPath": "/tmp/"
+            "LogFolderPath": "/tmp"
         },
     "globalConfig": [
         {
diff --git a/setup/dev/advancedsg.cfg b/setup/dev/advancedsg.cfg
index 01f7fcc4662..5fbd02e6b14 100644
--- a/setup/dev/advancedsg.cfg
+++ b/setup/dev/advancedsg.cfg
@@ -109,7 +109,7 @@
     },
     "logger": 
         {
-            "LogFolderPath": "/tmp/"
+            "LogFolderPath": "/tmp"
         },
     "globalConfig": [
         {
diff --git a/setup/dev/basic.cfg b/setup/dev/basic.cfg
index db8c59b09b4..b7f1486361a 100644
--- a/setup/dev/basic.cfg
+++ b/setup/dev/basic.cfg
@@ -110,7 +110,7 @@
     },
     "logger": 
         {
-            "LogFolderPath": "/tmp/"
+            "LogFolderPath": "/tmp"
         },
     "globalConfig": [
         {
diff --git a/setup/dev/local.cfg b/setup/dev/local.cfg
index 89d56a56664..954d75fc331 100644
--- a/setup/dev/local.cfg
+++ b/setup/dev/local.cfg
@@ -25,7 +25,7 @@
     },
     "logger":
     {
-            "LogFolderPath": "/tmp/"
+            "LogFolderPath": "/tmp"
     },
     "mgtSvr": [
         {
diff --git a/setup/dev/s3.cfg b/setup/dev/s3.cfg
index a865e0dbc82..de28e5b2698 100644
--- a/setup/dev/s3.cfg
+++ b/setup/dev/s3.cfg
@@ -115,7 +115,7 @@
     ],
     "logger":
     {
-            "LogFolderPath": "/tmp/"
+            "LogFolderPath": "/tmp"
     },
     "mgtSvr": [
         {
diff --git a/test/integration/component/test_tags.py b/test/integration/component/test_tags.py
index f9b0655016d..ed1aee7a0ee 100644
--- a/test/integration/component/test_tags.py
+++ b/test/integration/component/test_tags.py
@@ -185,9 +185,9 @@ def __init__(self):
                 "cidrlist": '0.0.0.0/0',
             },
             # Cent OS 5.3 (64 bit)
-            "sleep": 60,
+            "sleep": 5,
             "ostype": 'CentOS 5.3 (64-bit)',
-            "timeout": 10,
+            "timeout": 5,
             "mode": 'advanced',
         }
 
@@ -287,10 +287,12 @@ def tearDown(self):
             raise Exception("Warning: Exception during cleanup : %s" % e)
 
         for tag in self.rm_tags:
-            tag['tag_obj'].delete(self.apiclient, tag['resid'],
-                                  tag['restype'],
-                                  {tag['key']: tag['value']})
-
+            for concrete_tag in tag['tags']:
+                Tag.delete(self.apiclient,
+                           tag['resid'],
+                           tag['restype'],
+                           {concrete_tag['key']: concrete_tag['value']})
+                
         return
 
     @attr(tags=["advanced"], required_hardware="false")
@@ -404,7 +406,7 @@ def test_01_lbrule_tag(self):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=lb_rule.id,
                 resourceType='LoadBalancer',
@@ -541,7 +543,7 @@ def test_02_natrule_tag(self):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=nat_rule.id,
                 resourceType='portForwardingRule',
@@ -683,7 +685,7 @@ def test_03_firewallrule_tag(self):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=fw_rule.id,
                 resourceType='FirewallRule',
@@ -835,7 +837,7 @@ def test_04_vpn_tag(self):
         )
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=vpn.id,
                 resourceType='VPN',
@@ -876,12 +878,15 @@ def test_05_vm_tag(self):
         # 1. Create  a tag on VM using createTags API
         # 2. Delete above created tag using deleteTags API
 
+        tag_key = 'scope'
+        tag_value = 'test_05_vm_tag'
+        
         self.debug("Creating a tag for user VM")
         tag = Tag.create(
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -891,8 +896,8 @@ def test_05_vm_tag(self):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -901,15 +906,15 @@ def test_05_vm_tag(self):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             "The tag value should match with the original value"
         )
 
         vms = VirtualMachine.list(
             self.apiclient,
             listall=True,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
 
         self.assertEqual(
@@ -919,11 +924,11 @@ def test_05_vm_tag(self):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -935,8 +940,8 @@ def test_05_vm_tag(self):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -1031,7 +1036,7 @@ def test_06_template_tag(self):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.user_api_client,
                 resourceIds=template.id,
                 resourceType='Template',
@@ -1124,7 +1129,7 @@ def test_07_iso_tag(self):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=iso.id,
                 resourceType='ISO',
@@ -1152,12 +1157,15 @@ def test_07_iso_tag(self):
 
     @attr(tags=["advanced", "basic"], required_hardware="false")
     def test_08_volume_tag(self):
-        """ Test creation, listing and deletion tagson volume
+        """ Test creation, listing and deletion tags on volume
         """
         # Validate the following
         # 1. Create a tag on volume using createTags API
         # 2. Delete above created tag using deleteTags API
 
+        tag_key = 'scope'
+        tag_value = 'test_08_volume_tag'
+        
         if self.hypervisor.lower() == 'lxc':
             if not find_storage_pool_type(self.apiclient, storagetype='rbd'):
                 self.skipTest("RBD storage type is required for data volumes for LXC")
@@ -1181,7 +1189,7 @@ def test_08_volume_tag(self):
             self.apiclient,
             resourceIds=volume.id,
             resourceType='volume',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -1191,8 +1199,8 @@ def test_08_volume_tag(self):
             resourceType='volume',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1201,14 +1209,14 @@ def test_08_volume_tag(self):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
 
         vols = Volume.list(self.apiclient,
                            listall=True,
-                           key='region',
-                           value='India'
+                           key=tag_key,
+                           value=tag_value
                            )
         self.assertEqual(
             isinstance(vols, list),
@@ -1218,11 +1226,11 @@ def test_08_volume_tag(self):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=volume.id,
                 resourceType='volume',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -1234,7 +1242,7 @@ def test_08_volume_tag(self):
             resourceType='volume',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region'
+            key=tag_key
         )
         self.assertEqual(
             tags,
@@ -1245,7 +1253,7 @@ def test_08_volume_tag(self):
 
     @attr(tags=["advanced", "basic"], required_hardware="false")
     def test_09_snapshot_tag(self):
-        """ Test creation, listing and deletion tag son snapshot
+        """ Test creation, listing and deletion tags on snapshot
         """
         # Validate the following
         # 1. Create a tag on snapshot using createTags API
@@ -1321,7 +1329,7 @@ def test_09_snapshot_tag(self):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=snapshot.id,
                 resourceType='snapshot',
@@ -1350,12 +1358,15 @@ def test_09_snapshot_tag(self):
 
     @attr(tags=["advanced"], required_hardware="false")
     def test_10_network_tag(self):
-        """ Testcreation, listing and deletion tags on guest network
+        """ Test creation, listing and deletion tags on guest network
         """
         # Validate the following
         # 1. Create  a tag on Network using createTags API
         # 2. Delete above created tag using deleteTags API
 
+        tag_key = 'scope'
+        tag_value = 'test_10_network_tag'
+        
         self.debug("Fetching the network details for account: %s" %
                    self.account.name)
         networks = Network.list(
@@ -1378,7 +1389,7 @@ def test_10_network_tag(self):
             self.apiclient,
             resourceIds=network.id,
             resourceType='Network',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -1388,8 +1399,8 @@ def test_10_network_tag(self):
             resourceType='Network',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1398,7 +1409,7 @@ def test_10_network_tag(self):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
 
@@ -1407,8 +1418,8 @@ def test_10_network_tag(self):
             account=self.account.name,
             domainid=self.account.domainid,
             listall=True,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(networks, list),
@@ -1418,11 +1429,11 @@ def test_10_network_tag(self):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=network.id,
                 resourceType='Network',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -1434,8 +1445,8 @@ def test_10_network_tag(self):
             resourceType='Network',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -1452,6 +1463,9 @@ def test_11_migrate_tagged_vm_del(self):
         # 1. Create a tag on VM using createTags API
         # 2. Delete above created tag using deleteTags API
 
+        tag_key = 'scope'
+        tag_value = 'test_11_migrate_tagged_vm_del'
+        
         if self.hypervisor.lower() in ['lxc']:
             self.skipTest("vm migrate feature is not supported on %s" % self.hypervisor.lower())
 
@@ -1496,7 +1510,7 @@ def test_11_migrate_tagged_vm_del(self):
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -1506,8 +1520,8 @@ def test_11_migrate_tagged_vm_del(self):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1517,7 +1531,7 @@ def test_11_migrate_tagged_vm_del(self):
 
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
 
@@ -1527,11 +1541,11 @@ def test_11_migrate_tagged_vm_del(self):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -1543,8 +1557,8 @@ def test_11_migrate_tagged_vm_del(self):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -1562,12 +1576,15 @@ def test_13_tag_case_insensitive(self):
         # 2. Add same tag in upper case.
         # 3. Verify that tag creation failed.
 
+        tag_key = 'scope'
+        tag_value = 'test_13_tag_case_insensitive'
+        
         self.debug("Creating a tag for user VM")
         tag_1 = Tag.create(
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag_1.__dict__)
 
@@ -1577,8 +1594,8 @@ def test_13_tag_case_insensitive(self):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1588,25 +1605,25 @@ def test_13_tag_case_insensitive(self):
 
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
         try:
             Tag.create(self.apiclient,
                        resourceIds=self.vm_1.id,
                        resourceType='userVM',
-                       tags={'REGION': 'INDIA'})
+                       tags={tag_key.upper(): tag_value.uppper()})
         except Exception as e:
             pass
         else:
             assert("Creating same tag in upper case succeeded")
 
         try:
-            tag_1.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -1618,8 +1635,8 @@ def test_13_tag_case_insensitive(self):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -1637,13 +1654,16 @@ def test_14_special_char_mutiple_tags(self):
         # 1. Create more than 10 tags to VM using createTags API
         # 2. Create a tag with special characters on VM using createTags API
 
+        tag_key = 'scope'
+        tag_value = 'test_14_special_char_mutiple_tags'
+        
         self.debug("Creating a tag for user VM")
         tag = Tag.create(
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
             tags={
-                'region': 'India',
+                tag_key: tag_value,
                 'offering': 'high',
                 'type': 'webserver',
                 'priority': 'critical',
@@ -1664,8 +1684,8 @@ def test_14_special_char_mutiple_tags(self):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1674,16 +1694,16 @@ def test_14_special_char_mutiple_tags(self):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
         # Cleanup
-        tag.delete(
+        Tag.delete(
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
             tags={
-                'region': 'India',
+                tag_key: tag_value,
                 'offering': 'high',
                 'type': 'webserver',
                 'priority': 'critical',
@@ -1707,6 +1727,9 @@ def test_15_project_tag(self):
         # 2. Create a tag on projects using createTags API
         # 3. Delete the tag.
 
+        tag_key = 'scope'
+        tag_value = 'test_15_project_tag'
+                        
         # Create project as a domain admin
         project = Project.create(
             self.apiclient,
@@ -1724,7 +1747,7 @@ def test_15_project_tag(self):
             self.apiclient,
             resourceIds=project.id,
             resourceType='project',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -1733,7 +1756,7 @@ def test_15_project_tag(self):
             listall=True,
             resourceType='project',
             resourceIds=project.id,
-            key='region',
+            key=tag_key,
         )
         self.debug("tags = %s" % tags)
 
@@ -1744,15 +1767,15 @@ def test_15_project_tag(self):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
 
         projects = Project.list(
             self.apiclient,
             listall=True,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
 
         self.assertEqual(
@@ -1763,11 +1786,11 @@ def test_15_project_tag(self):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=project.id,
                 resourceType='project',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -1779,8 +1802,8 @@ def test_15_project_tag(self):
             resourceType='project',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -1799,8 +1822,11 @@ def test_16_query_tags_other_account(self):
         # 3. Login with other account and query the tags using
         #    listTags API
 
+        tag_key = 'scope'
+        tag_value = 'test_16_query_tags_other_account'
+        
         self.debug("Creating user accounts..")
-
+        
         user_account = Account.create(
             self.apiclient,
             self.services["user"],
@@ -1836,7 +1862,7 @@ def test_16_query_tags_other_account(self):
             self.apiclient,
             resourceIds=iso.id,
             resourceType='ISO',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -1846,7 +1872,7 @@ def test_16_query_tags_other_account(self):
             resourceType='ISO',
             account=user_account.name,
             domainid=user_account.domainid,
-            key='region',
+            key=tag_key,
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1855,7 +1881,7 @@ def test_16_query_tags_other_account(self):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             "The tag value should match with the original value"
         )
 
@@ -1866,7 +1892,7 @@ def test_16_query_tags_other_account(self):
             resourceType='ISO',
             account=other_user_account.name,
             domainid=other_user_account.domainid,
-            key='region',
+            key=tag_key,
         )
 
         self.assertEqual(
@@ -1875,6 +1901,16 @@ def test_16_query_tags_other_account(self):
             "List tags should return empty response"
         )
 
+        try:
+            Tag.delete(
+                self.apiclient,
+                resourceIds=iso.id,
+                resourceType='ISO',
+                tags={tag_key: tag_value}
+            )
+        except Exception as e:
+            self.fail("Failed to delete the tag - %s" % e)
+                        
         return
 
     @attr(tags=["advanced", "basic"], required_hardware="false")
@@ -1887,6 +1923,9 @@ def test_17_query_tags_admin_account(self):
         # 3. Login with admin account and query the tags using
         #    listTags API
 
+        tag_key = 'scope'
+        tag_value = 'test_17_query_tags_admin_account'
+        
         self.debug("Creating user accounts..")
 
         user_account = Account.create(
@@ -1913,7 +1952,7 @@ def test_17_query_tags_admin_account(self):
         Tag.create(self.apiclient,
                    resourceIds=iso.id,
                    resourceType='ISO',
-                   tags={'region': 'India'})
+                   tags={tag_key: tag_value})
 
         tags = Tag.list(
             self.apiclient,
@@ -1921,7 +1960,7 @@ def test_17_query_tags_admin_account(self):
             resourceType='ISO',
             account=user_account.name,
             domainid=user_account.domainid,
-            key='region',
+            key=tag_key,
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1930,7 +1969,7 @@ def test_17_query_tags_admin_account(self):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             "The tag value should match with the original value"
         )
 
@@ -1939,7 +1978,7 @@ def test_17_query_tags_admin_account(self):
             self.apiclient,
             listall=True,
             resourceType='ISO',
-            key='region',
+            key=tag_key,
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1948,10 +1987,20 @@ def test_17_query_tags_admin_account(self):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
 
+        try:
+            Tag.delete(
+                self.apiclient,
+                resourceIds=iso.id,
+                resourceType='ISO',
+                tags={tag_key: tag_value}
+            )
+        except Exception as e:
+            self.fail("Failed to delete the tag - %s" % e)
+        
         return
 
     @attr(tags=["advanced", "basic", "simulator"], required_hardware="false")
@@ -1962,12 +2011,15 @@ def test_18_invalid_list_parameters(self):
         # 1. Create a tag on  supported resource type(ex:vms)
         # 2. Run the list API commands  with passing invalid key parameter
 
+        tag_key = 'scope'
+        tag_value = 'test_18_invalid_list_parameters'
+        
         self.debug("Creating a tag for user VM")
         tag = Tag.create(
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -1979,14 +2031,15 @@ def test_18_invalid_list_parameters(self):
         self.rm_tags.append({'tag_obj': tag,
                              'restype': 'userVM',
                              'resid': self.vm_1.id,
-                             'key': 'region',
-                             'value': 'India'})
+                             'tags': [
+                                 {'key': tag_key, 'value': tag_value}
+                             ]})
 
         self.debug("Passing invalid key parameter to the listAPI for vms")
 
         vms = VirtualMachine.list(self.apiclient,
-                                  **{'tags[0].key': 'region111',
-                                     'tags[0].value': 'India',
+                                  **{'tags[0].key': tag_key + '1',
+                                     'tags[0].value': tag_value,
                                      'listall': 'True'}
                                   )
         self.assertEqual(
@@ -2006,12 +2059,15 @@ def test_19_delete_add_same_tag(self):
         # 1. Deletion of a tag without any errors.
         # 2. Add same tag.
 
+        tag_key = 'scope'
+        tag_value = 'test_19_delete_add_same_tag'        
+        
         self.debug("Creating a tag for user VM")
         tag = Tag.create(
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -2021,8 +2077,8 @@ def test_19_delete_add_same_tag(self):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -2032,17 +2088,17 @@ def test_19_delete_add_same_tag(self):
 
         self.assertEqual(
             tags[0].value,
-            "India",
+            tag_value,
             "Tag created with incorrect value"
         )
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -2054,8 +2110,8 @@ def test_19_delete_add_same_tag(self):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -2067,7 +2123,7 @@ def test_19_delete_add_same_tag(self):
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -2077,8 +2133,8 @@ def test_19_delete_add_same_tag(self):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -2087,17 +2143,17 @@ def test_19_delete_add_same_tag(self):
         )
 
         self.assertEqual(tags[0].value,
-                         "India",
+                         tag_value,
                          "Tag created with incorrect value"
                          )
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -2107,8 +2163,11 @@ def test_19_delete_add_same_tag(self):
     def test_20_create_tags_multiple_resources(self):
         "Test creation of same tag on multiple resources"
 
-        self.debug("Creating volume for account: %s " %
-                   self.account.name)
+        tag_key = 'scope'
+        tag_value = 'test_20_create_tags_multiple_resources'
+                        
+        self.debug("Creating volume for account: %s " % self.account.name)
+        
         volume = Volume.create(
             self.apiclient,
             self.services["volume"],
@@ -2126,7 +2185,7 @@ def test_20_create_tags_multiple_resources(self):
             self.apiclient,
             resourceIds=volume.id,
             resourceType='volume',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -2136,7 +2195,7 @@ def test_20_create_tags_multiple_resources(self):
             resourceType='volume',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
+            key=tag_key,
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -2145,7 +2204,7 @@ def test_20_create_tags_multiple_resources(self):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
 
@@ -2154,7 +2213,7 @@ def test_20_create_tags_multiple_resources(self):
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -2164,8 +2223,8 @@ def test_20_create_tags_multiple_resources(self):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -2175,17 +2234,17 @@ def test_20_create_tags_multiple_resources(self):
 
         self.assertEqual(
             tags[0].value,
-            "India",
-            "Tag created with incorrect value"
+            tag_value,
+            "Expected tag value is incorrect"
         )
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -2197,8 +2256,8 @@ def test_20_create_tags_multiple_resources(self):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -2212,6 +2271,9 @@ def test_20_create_tags_multiple_resources(self):
     def test_21_create_tag_stopped_vm(self):
         "Test creation of tag on stopped vm."
 
+        tag_key = 'scope'
+        tag_value = 'test_21_create_tag_stopped_vm'        
+        
         try:
             self.debug("Stopping the virtual machine: %s" % self.vm_1.name)
             # Stop virtual machine
@@ -2222,7 +2284,7 @@ def test_21_create_tag_stopped_vm(self):
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
             self.debug("Tag created: %s" % tag.__dict__)
 
@@ -2232,8 +2294,8 @@ def test_21_create_tag_stopped_vm(self):
                 resourceType='userVM',
                 account=self.account.name,
                 domainid=self.account.domainid,
-                key='region',
-                value='India'
+                key=tag_key,
+                value=tag_value
             )
             self.assertEqual(
                 isinstance(tags, list),
@@ -2243,16 +2305,16 @@ def test_21_create_tag_stopped_vm(self):
 
             self.assertEqual(
                 tags[0].value,
-                "India",
+                tag_value,
                 "Tag created with incorrect value"
             )
 
             self.debug("Deleting the created tag..")
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Exception occured - %s" % e)
@@ -2262,6 +2324,9 @@ def test_21_create_tag_stopped_vm(self):
     def test_22_create_tag_destroyed_vm(self):
         "Test creation of tag on stopped vm."
 
+        tag_key = 'scope'
+        tag_value = 'test_22_create_tag_destroyed_vm'
+        
         self.debug("Destroying instance: %s" % self.vm_1.name)
         self.vm_1.delete(self.apiclient, expunge=False)
 
@@ -2270,7 +2335,7 @@ def test_22_create_tag_destroyed_vm(self):
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -2280,8 +2345,8 @@ def test_22_create_tag_destroyed_vm(self):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -2291,17 +2356,17 @@ def test_22_create_tag_destroyed_vm(self):
 
         self.assertEqual(
             tags[0].value,
-            "India",
+            tag_value,
             "Tag created with incorrect value"
         )
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -2405,8 +2470,8 @@ def test_23_list_untagged_host_for_vm_migration(self):
         return
 
     @attr(tags=["advanced"], required_hardware="false")
-    def test_24_public_IP_tag(self):
-        """ Testcreation, adding and removing tag on public IP address
+    def test_24_public_ip_tag(self):
+        """ Test creation, adding and removing tag on public IP address
         """
         # Validate the following
         # 1. Create a domain and admin account under the new domain
@@ -2414,6 +2479,9 @@ def test_24_public_IP_tag(self):
         # 3. Delete above created tag using deleteTags API
         # 4. Perform steps 2&3 using domain-admin
 
+        tag_key = 'scope'
+        tag_value = 'test_24_public_ip_tag'
+                
         self.debug("Creating a sub-domain under: %s" % self.domain.name)
         self.child_domain = Domain.create(
             self.apiclient,
@@ -2479,7 +2547,7 @@ def test_24_public_IP_tag(self):
             self.dom_admin_api_client,
             resourceIds=public_ip.ipaddress.id,
             resourceType='PublicIpAddress',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -2489,8 +2557,8 @@ def test_24_public_IP_tag(self):
             resourceType='PublicIpAddress',
             account=self.child_do_admin.name,
             domainid=self.child_do_admin.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -2499,7 +2567,7 @@ def test_24_public_IP_tag(self):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
         publicIps = PublicIPAddress.list(
@@ -2507,8 +2575,8 @@ def test_24_public_IP_tag(self):
             account=self.child_do_admin.name,
             domainid=self.child_do_admin.domainid,
             listall=True,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(publicIps, list),
@@ -2518,11 +2586,11 @@ def test_24_public_IP_tag(self):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.dom_admin_api_client,
                 resourceIds=public_ip.ipaddress.id,
                 resourceType='PublicIpAddress',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -2534,8 +2602,8 @@ def test_24_public_IP_tag(self):
             resourceType='PublicIpAddress',
             account=self.child_do_admin.name,
             domainid=self.child_do_admin.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -2543,3 +2611,366 @@ def test_24_public_IP_tag(self):
             "List tags should return empty response"
         )
         return
+
+    def __test_account_tags(self, apiclient, account, listall = False):
+        set_tags = {'primary-contact-name': 'John Doe',
+                    'primary-contact-phone': '1-022-333-444'}
+
+        Tag.create(
+            apiclient,
+            resourceIds=account.id,
+            resourceType='Account',
+            tags=set_tags)
+
+        received_tags = Tag.list(
+            apiclient,
+            resourceId=account.id,
+            listAll=listall,
+            resourceType='Account')
+
+        self.assertEqual(
+            isinstance(received_tags, list),
+            True,
+            "List tags should return list response."
+        )
+
+        received_tag_map = {}
+        for t in received_tags:
+            received_tag_map[t.key] = t.value
+        
+        self.assertEqual(
+            set_tags,
+            received_tag_map,
+            "Tags saved and received differ."
+        )
+
+        try:
+            Tag.delete(
+                apiclient,
+                resourceIds=account.id,
+                resourceType='Account',
+                tags=set_tags)
+        except Exception as e:
+            self.fail("Failed to delete the tag - %s" % e)
+
+        received_tags_removed = Tag.list(
+            apiclient,
+            resourceId=account.id,
+            listAll=listall,
+            resourceType='Account')
+
+        self.assertEqual(
+            received_tags_removed,
+            None,
+            "List tags should return empty list response when tags are removed."
+        )
+        return
+    
+    @attr(tags=["advanced","basic"], required_hardware="false")
+    def test_25_admin_account_tags(self):
+        '''Test create, list, delete tag for admin account from admin account'''
+        self.debug("Creating a tag for Admin account")
+        admin_account = Account.list(self.apiclient, name='admin')
+        self.__test_account_tags(self.apiclient, admin_account[0])
+        return
+
+    @attr(tags=["advanced","basic"], required_hardware="false")    
+    def test_26_domain_admin_account_tags(self):
+        child_domain = Domain.create(
+            self.apiclient,
+            services=self.services["domain"],
+            parentdomainid=self.domain.id
+        )
+        child_domain_admin = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=True,
+            domainid=child_domain.id
+        )
+        # Cleanup the resources created at end of test
+        self.cleanup.append(child_domain_admin)
+        self.cleanup.append(child_domain)
+        domain_admin_api_client = self.testClient.getUserApiClient(
+            UserName=child_domain_admin.name,
+            DomainName=child_domain_admin.domain
+        )
+        self.__test_account_tags(domain_admin_api_client, child_domain_admin)
+        return
+
+    @attr(tags=["advanced","basic"], required_hardware="false")
+    def test_27_regular_user_account_tags(self):
+        regular_account = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=False,
+            domainid=self.domain.id
+        )
+        # Cleanup the resources created at end of test
+        self.cleanup.append(regular_account)
+        regular_account_api_client = self.testClient.getUserApiClient(UserName=regular_account.name, DomainName=self.domain.name)
+        self.__test_account_tags(regular_account_api_client, regular_account)
+        return
+    
+    @attr(tags=["advanced","basic"], required_hardware="false")
+    def test_28_admin_access_domain_admin_account_tags(self):
+        '''Test create, list, delete tag for domain admin account from admin account'''
+        child_domain = Domain.create(
+            self.apiclient,
+            services=self.services["domain"],
+            parentdomainid=self.domain.id
+        )
+        child_domain_admin = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=True,
+            domainid=child_domain.id
+        )
+        # Cleanup the resources created at end of test
+        self.cleanup.append(child_domain_admin)
+        self.cleanup.append(child_domain)
+        self.__test_account_tags(self.apiclient, child_domain_admin, listall = True)
+        return
+
+    @attr(tags=["advanced","basic"], required_hardware="false")
+    def test_29_admin_access_user_account_tags(self):
+        '''Test create, list, delete tag for user account from admin account'''
+        regular_account = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=False
+        )
+        # Cleanup the resources created at end of test
+        self.cleanup.append(regular_account)
+        self.__test_account_tags(self.apiclient, regular_account, listall = True)
+        return
+
+    @attr(tags=["advanced","basic"], required_hardware="false")
+    def test_30_domain_admin_access_user_account_same_domain_tags(self):
+        '''Test create, list, delete tag for user account from admin account'''
+
+        child_domain = Domain.create(
+            self.apiclient,
+            services=self.services["domain"],
+            parentdomainid=self.domain.id
+        )
+        child_domain_admin = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=True,
+            domainid=child_domain.id
+        )
+
+        regular_account = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=False,
+            domainid=child_domain.id
+        )
+        # Cleanup the resources created at end of test
+        self.cleanup.append(regular_account)
+                                
+        # Cleanup the resources created at end of test
+        self.cleanup.append(child_domain_admin)
+        self.cleanup.append(child_domain)
+
+        domain_admin_api_client = self.testClient.getUserApiClient(
+            UserName=child_domain_admin.name,
+            DomainName=child_domain.name
+        )
+        self.__test_account_tags(domain_admin_api_client, regular_account, listall = True)
+        return
+
+    @attr(tags=["advanced","basic"], required_hardware="false")
+    def test_31_user_cant_remove_update_admin_tags(self):
+        '''Tests that an user is unable to remove, modify tags created by admin but should access'''
+
+        tag_key_user = 'scope_user'
+        tag_value_user = 'test_31_user_cant_remove_update_admin_tags'
+
+        tag_key_admin = 'scope_admin'
+        tag_value_admin = 'test_31_user_cant_remove_update_admin_tags'
+                       
+        regular_account = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=False
+        )
+        self.cleanup.append(regular_account)
+        
+        regular_account_api_client = self.testClient.getUserApiClient(UserName=regular_account.name, DomainName=self.domain.name)
+
+        def create_admin_tag():
+            return Tag.create(
+                self.apiclient,
+                resourceIds=regular_account.id,
+                resourceType='Account',
+                tags={ tag_key_admin: tag_value_admin})
+            
+
+        def create_user_tag():
+            return Tag.create(
+                regular_account_api_client,
+                resourceIds=regular_account.id,
+                resourceType='Account',
+                tags={ tag_key_user: tag_value_user})
+            
+        create_admin_tag()
+        create_user_tag()
+
+        #
+        # List test expressions
+        #
+        def list_tags(apiclient, listAll):
+            return Tag.list(
+                apiclient,
+                resourceId=regular_account.id,
+                listAll=listAll,
+                resourceType='Account')
+
+        def tags_to_map(tags):
+            m = {}
+            for t in tags:
+                m[t.key] = t.value                            
+            return m
+
+        # admin requests user account tags and gets None (without listall)
+        received_tags_admin = list_tags(self.apiclient, False)
+        self.assertEqual(
+            received_tags_admin,
+            None,
+            "List tags should return empty list response when tags are not set on self-owned account."
+        )
+
+        # admin requests user account tags and gets all (with listall)
+        received_tags_admin_listall = list_tags(self.apiclient, True)
+        self.assertEqual(
+            tags_to_map(received_tags_admin_listall),
+            {tag_key_admin: tag_value_admin, tag_key_user: tag_value_user},
+            "List (with listAll=true) tags should return information for admin tags and user tags"
+        )
+
+        # user requests own account tags and receives all (without listall)
+        received_tags_user = list_tags(regular_account_api_client, False)
+        self.assertEqual(
+            tags_to_map(received_tags_user),
+            {tag_key_admin: tag_value_admin, tag_key_user: tag_value_user},
+            "List (with listAll=false) tags should return information for user tags"
+        )       
+
+        # user requests own account tags and receives all (with listall)
+        received_tags_user_listall = list_tags(regular_account_api_client, True)
+        self.assertEqual(
+            tags_to_map(received_tags_user_listall),
+            {tag_key_admin: tag_value_admin, tag_key_user: tag_value_user},
+            "List (with listAll=false) tags should return information for user tags"
+        )
+       
+        #
+        # Delete test expressions
+        #
+        
+        def delete_tags(apiclient, tags):
+            Tag.delete(
+                apiclient,
+                resourceIds=regular_account.id,
+                resourceType='Account',
+                tags=tags)
+
+        # user tries to delete admin tag on own account and succeeds 
+        try:
+            delete_tags(regular_account_api_client, {tag_key_admin: tag_value_admin})
+        except Exception as e:
+            self.fail("Regular user is not able to delete administrator tag on own account - %s" % e)
+                        
+        # user tries to delete user tag and succeeds
+        try:
+            delete_tags(regular_account_api_client, {tag_key_user: tag_value_user})
+        except Exception as e:
+            self.fail("Regular user is not able to delete own tag - %s" % e)
+
+        # recover tag to run admin tests
+        create_user_tag()
+        create_admin_tag()
+                
+        # admin tries to delete tags and succeeds
+        try:
+            delete_tags(self.apiclient, {tag_key_admin: tag_value_admin, tag_key_user: tag_value_user})
+        except Exception as e:
+            self.fail("Administrator is not able to delete a tag - %s" % e)        
+
+        return
+            
+    @attr(tags=["advanced","basic"], required_hardware="false")
+    def test_32_user_a_doesnt_have_access_to_user_b_tags(self):
+        '''Test resource security between regular accounts A and B'''
+
+        tag_key_user1 = 'scope_user1'
+        tag_value_user1 = 'test_32_user_a_doesnt_have_access_to_user_b_tags-user1'
+
+        tag_key_user2 = 'scope_user2'
+        tag_value_user2 = 'test_32_user_a_doesnt_have_access_to_user_b_tags-user2'
+                
+        regular_account1 = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=False
+        )
+        self.cleanup.append(regular_account1)
+
+        regular_account_api_client1 = self.testClient.getUserApiClient(UserName=regular_account1.name, DomainName=self.domain.name)
+
+        regular_account2 = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=False
+        )
+        self.cleanup.append(regular_account2)
+
+        regular_account_api_client2 = self.testClient.getUserApiClient(UserName=regular_account2.name, DomainName=self.domain.name)
+
+        Tag.create(
+            regular_account_api_client1,
+            resourceIds=regular_account1.id,
+            resourceType='Account',
+            tags={tag_key_user1: tag_value_user1})
+
+        Tag.create(
+            regular_account_api_client2,
+            resourceIds=regular_account2.id,
+            resourceType='Account',
+            tags={tag_key_user2: tag_value_user2})
+
+        try:
+            Tag.list(
+                regular_account_api_client1,
+                resourceId=regular_account2.id,
+                listAll=listAll,
+                resourceType='Account')
+        except Exception as e:
+            pass
+        else:
+            self.fail("User1 has access to list tags of User2.")
+
+        try:
+            Tag.delete(
+                regular_account_api_client1,
+                resourceIds=regular_account2.id,
+                resourceType='Account',
+                tags={tag_key_user2: tag_value_user2})
+        except Exception as e:
+            pass
+        else:
+            self.fail("User1 has access to delete tags of User2.")                    
+
+        try:
+            Tag.create(
+                regular_account_api_client1,
+                resourceIds=regular_account2.id,
+                resourceType='Account',
+                tags={tag_key_user1: tag_value_user1})
+        except Exception as e:
+            pass
+        else:
+            self.fail("User1 has access to create tags for User2.")
+                                
+        return
diff --git a/tools/marvin/marvin/cloudstackConnection.py b/tools/marvin/marvin/cloudstackConnection.py
index d044fdd0eb4..826069742fe 100644
--- a/tools/marvin/marvin/cloudstackConnection.py
+++ b/tools/marvin/marvin/cloudstackConnection.py
@@ -103,8 +103,8 @@ def __poll(self, jobid, response_cmd):
                     elif job_status == JOB_FAILED:
                         raise Exception("Job failed: %s"\
                                          % async_response)
-                time.sleep(5)
-                timeout -= 5
+                time.sleep(1)
+                timeout -= 1
                 self.logger.debug("=== JobId:%s is Still Processing, "
                                   "Will TimeOut in:%s ====" % (str(jobid),
                                                                str(timeout)))
diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py
index 8d553c872e1..0ef3f3c3ea9 100644
--- a/tools/marvin/marvin/deployDataCenter.py
+++ b/tools/marvin/marvin/deployDataCenter.py
@@ -35,6 +35,7 @@ class DeleteDataCenters: Deletes a DataCenter based upon the dc cfg
 from marvin.config.test_data import test_data
 from sys import exit
 import os
+import errno
 import pickle
 from time import sleep, strftime, localtime
 from optparse import OptionParser
@@ -65,18 +66,16 @@ def __init__(self,
     def __persistDcConfig(self):
         try:
             if self.__logFolderPath:
-                dc_file_path = self.__logFolderPath + "/dc_entries.obj"
+                dc_file_path = os.path.join(self.__logFolderPath, "dc_entries.obj")
             else:
                 ts = strftime("%b_%d_%Y_%H_%M_%S", localtime())
                 dc_file_path = "dc_entries_" + str(ts) + ".obj"
+
             file_to_write = open(dc_file_path, 'w')
             if file_to_write:
                 pickle.dump(self.__cleanUp, file_to_write)
-                print "\n=== Data Center Settings are dumped to %s===" % \
-                      dc_file_path
-                self.__tcRunLogger.debug(
-                    "\n=== Data Center Settings are dumped to %s===" %
-                    dc_file_path)
+                print "\n=== Data Center Settings are dumped to %s===" % dc_file_path
+                self.__tcRunLogger.debug("\n=== Data Center Settings are dumped to %s===" % dc_file_path)
         except Exception as e:
             print "Exception Occurred  while persisting DC Settings: %s" % \
                   GetDetailExceptionInfo(e)
@@ -1110,38 +1109,46 @@ def removeDataCenter(self):
         finally:
             return ret
 
+def mkdirpath(path):
+    try:
+        os.makedirs(path)
+    except OSError as exc:
+        if exc.errno == errno.EEXIST and os.path.isdir(path):
+            pass
+        else:
+            raise
 
 if __name__ == "__main__":
     '''
     @Desc : This module facilitates the following:
             1. Deploying DataCenter by using the input provided
             configuration.
-              EX: python deployDataCenter.py -i <inp-cfg-file>
+              EX: python deployDataCenter.py -i <inp-cfg-file> [-l <directory with logs and output data location>]
             2. Removes a created DataCenter by providing
             the input configuration file and data center settings file
               EX: python deployDataCenter.py -i <inp-cfg-file>
-              -r <dc_exported_entries>
+              -r <dc_exported_entries> [-l <directory with logs and output data location>] 
     '''
     parser = OptionParser()
-    parser.add_option("-i", "--input", action="store",
-                      default=None, dest="input",
-                      help="the path \
-                      where the json config file generated")
-
-    parser.add_option("-r", "--remove", action="store",
-                      default=None, dest="remove",
-                      help="path to file\
-                      where the created dc entries are kept")
+    parser.add_option("-i", "--input", action="store", default=None, dest="input",
+                      help="The path where the json zones config file is located.")
+
+    parser.add_option("-r", "--remove", action="store", default=None, dest="remove",
+                      help="The path to file where the created dc entries are kept.")
+
+    parser.add_option("-l", "--logdir", action="store", default=None, dest="logdir",
+                      help="The directory where result logs of running the script are stored:"
+                      "[dc_entries.obj, failed_plus_exceptions.txt, runinfo.txt]." +
+                      "Created automatically if doesn't exists.")
+
     (options, args) = parser.parse_args()
 
     '''
     Verify the input validity
     '''
     if options.input is None and options.remove is None:
-        print "\n==== For DeployDataCenter: Please Specify a " \
-              "Valid Input Configuration File===="
-        print "\n==== For DeleteDataCenters: Please Specify a " \
-              "Valid Input Configuration File and DC Settings===="
+        print "\n==== For DeployDataCenter: Please Specify a valid Input Configuration File===="
+        print "\n==== For DeleteDataCenters: Please Specify a valid Input Configuration File and DC Settings===="
         exit(1)
 
     '''
@@ -1161,8 +1168,10 @@ def removeDataCenter(self):
     cfg = configGenerator.getSetupConfig(options.input)
     log = cfg.logger
 
-    ret = log_obj.createLogs("DeployDataCenter",
-                             log)
+    if options.logdir != None:
+        mkdirpath(options.logdir)
+
+    ret = log_obj.createLogs("DeployDataCenter", log, options.logdir, options.logdir == None)
     if ret != FAILED:
         log_folder_path = log_obj.getLogFolderPath()
         tc_run_logger = log_obj.getLogger()
diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py
index a3f1043e654..55c32b27f20 100755
--- a/tools/marvin/marvin/lib/base.py
+++ b/tools/marvin/marvin/lib/base.py
@@ -4300,7 +4300,8 @@ def create(cls, apiclient, resourceIds, resourceType, tags):
             })
         return Tag(apiclient.createTags(cmd).__dict__)
 
-    def delete(self, apiclient, resourceIds, resourceType, tags):
+    @classmethod
+    def delete(cls, apiclient, resourceIds, resourceType, tags):
         """Delete tags"""
 
         cmd = deleteTags.deleteTagsCmd()
diff --git a/tools/marvin/marvin/marvinLog.py b/tools/marvin/marvin/marvinLog.py
index ea8eaee7dff..582d2e14457 100644
--- a/tools/marvin/marvin/marvinLog.py
+++ b/tools/marvin/marvin/marvinLog.py
@@ -128,7 +128,7 @@ def getLogFolderPath(self):
     def createLogs(self,
                    test_module_name=None,
                    log_cfg=None,
-                   user_provided_logpath=None):
+                   user_provided_logpath=None, use_temp_path=True):
         '''
         @Name : createLogs
         @Desc : Gets the Logger with file paths initialized and created
@@ -140,29 +140,34 @@ def createLogs(self,
                                        If user provided log path
                                        is available, then one in cfg
                                        will  not be picked up.
+                 use_temp_path: Boolean value which specifies either logs will
+                                       be prepended by random path or not.
         @Output : SUCCESS\FAILED
         '''
         try:
-            temp_ts = time.strftime("%b_%d_%Y_%H_%M_%S",
-                                    time.localtime())
+            temp_ts = time.strftime("%b_%d_%Y_%H_%M_%S", time.localtime())
+
             if test_module_name is None:
                 temp_path = temp_ts + "_" + random_gen()
             else:
-                temp_path = str(test_module_name) + \
-                    "__" + str(temp_ts) + "_" + random_gen()
+                temp_path = str(test_module_name) + "__" + str(temp_ts) + "_" + random_gen()
 
             if user_provided_logpath:
-                temp_dir = user_provided_logpath + "/MarvinLogs"
+                temp_dir = os.path.join(user_provided_logpath, "MarvinLogs")
             elif ((log_cfg is not None) and
                     ('LogFolderPath' in log_cfg.__dict__.keys()) and
                     (log_cfg.__dict__.get('LogFolderPath') is not None)):
-                temp_dir = \
-                    log_cfg.__dict__.get('LogFolderPath') + "/MarvinLogs"
+                temp_dir = os.path.join(log_cfg.__dict__.get('LogFolderPath'), "MarvinLogs")
+
+            if use_temp_path == True:
+                self.__logFolderDir = os.path.join(temp_dir, temp_path)
+            else:
+                if test_module_name == None:
+                    self.__logFolderDir = temp_dir
+                else:
+                    self.__logFolderDir = os.path.join(temp_dir, str(test_module_name))
 
-            self.__logFolderDir = temp_dir + "//" + temp_path
-            print "\n==== Log Folder Path: %s. " \
-                  "All logs will be available here ====" \
-                  % str(self.__logFolderDir)
+            print "\n==== Log Folder Path: %s. All logs will be available here ====" % str(self.__logFolderDir)
             os.makedirs(self.__logFolderDir)
 
             '''
@@ -171,9 +176,10 @@ def createLogs(self,
             2. RunLog contains the complete Run Information for Test Run
             3. ResultFile contains the TC result information for Test Run
             '''
-            tc_failed_exception_log = \
-                self.__logFolderDir + "/failed_plus_exceptions.txt"
-            tc_run_log = self.__logFolderDir + "/runinfo.txt"
+
+            tc_failed_exception_log = os.path.join(self.__logFolderDir, "failed_plus_exceptions.txt")
+            tc_run_log = os.path.join(self.__logFolderDir, "runinfo.txt")
+
             if self.__setLogHandler(tc_run_log,
                                     log_level=logging.DEBUG) != FAILED:
                 self.__setLogHandler(tc_failed_exception_log,


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services