# 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 tags
"""
#Import Local Modules
import marvin
from nose.plugins.attrib import attr
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
from marvin.integration.lib.utils import *
from marvin.integration.lib.base import *
from marvin.integration.lib.common import *
import datetime


class Services:
    """Test tags Services
    """

    def __init__(self):
        self.services = {
                        "domain": {
                                   "name": "Domain",
                        },
                        "project": {
                                    "name": "Project",
                                    "displaytext": "Test project",
                        },
                        "account": {
                                    "email": "administrator@clogeny.com",
                                    "firstname": "Test",
                                    "lastname": "User",
                                    "username": "test",
                                    # Random characters are appended for unique
                                    # username
                                    "password": "password",
                         },
                         "user": {
                                    "email": "user@clogeny.com",
                                    "firstname": "User",
                                    "lastname": "User",
                                    "username": "User",
                                    # Random characters are appended for unique
                                    # username
                                    "password": "password",
                         },
                        "other_user": {
                                    "email": "otheruser@clogeny.com",
                                    "firstname": "Other",
                                    "lastname": "User",
                                    "username": "User",
                                    # Random characters are appended for unique
                                    # username
                                    "password": "password",
                         },
                         "service_offering": {
                                    "name": "Tiny Instance",
                                    "displaytext": "Tiny Instance",
                                    "cpunumber": 1,
                                    "cpuspeed": 100,
                                    # in MHz
                                    "memory": 128,
                                    # In MBs
                        },
                        "disk_offering": {
                                    "displaytext": "Tiny Disk Offering",
                                    "name": "Tiny Disk Offering",
                                    "disksize": 1
                        },
                        "volume": {
                                   "diskname": "Test Volume",
                        },
                        "virtual_machine": {
                                    "displayname": "TestVM",
                                    "username": "root",
                                    "password": "password",
                                    "ssh_port": 22,
                                    "hypervisor": 'XenServer',
                                    "privateport": 22,
                                    "publicport": 22,
                                    "protocol": 'TCP',
                        },
                        "template": {
                                    "displaytext": "Cent OS Template",
                                    "name": "Cent OS Template",
                                    "ostype": 'CentOS 5.3 (64-bit)',
                                    "templatefilter": 'self',
                        },
                        "iso":
                        {
                            "displaytext": "Dummy ISO",
                            "name": "Dummy ISO",
                            "url": "http://people.apache.org/~tsp/dummy.iso",
                            # Source URL where ISO is located
                            "isextractable": True,
                            "isfeatured": True,
                            "ispublic": False,
                            "ostype": 'CentOS 5.3 (64-bit)',
                            "mode": 'HTTP_DOWNLOAD',
                            # Used in Extract template, value must be HTTP_DOWNLOAD
                        },
                        "network_offering": {
                                    "name": 'Network offering-VR services',
                                    "displaytext": 'Network offering-VR services',
                                    "guestiptype": 'Isolated',
                                    "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat',
                                    "traffictype": 'GUEST',
                                    "availability": 'Optional',
                                    "serviceProviderList": {
                                            "Dhcp": 'VirtualRouter',
                                            "Dns": 'VirtualRouter',
                                            "SourceNat": 'VirtualRouter',
                                            "PortForwarding": 'VirtualRouter',
                                            "Vpn": 'VirtualRouter',
                                            "Firewall": 'VirtualRouter',
                                            "Lb": 'VirtualRouter',
                                            "UserData": 'VirtualRouter',
                                            "StaticNat": 'VirtualRouter',
                                        },
                                    },
                         "network": {
                                  "name": "Test Network",
                                  "displaytext": "Test Network",
                                },
                         "lbrule": {
                                    "name": "SSH",
                                    "alg": "leastconn",
                                    # Algorithm used for load balancing
                                    "privateport": 22,
                                    "publicport": 22,
                                    "openfirewall": False,
                         },
                         "natrule": {
                                    "privateport": 22,
                                    "publicport": 22,
                                    "protocol": "TCP"
                                },
                         "fw_rule": {
                                    "startport": 1,
                                    "endport": 6000,
                                    "cidr": '55.55.0.0/11',
                                    # Any network (For creating FW rule)
                                },
                         "security_group": {
                                    "name": 'SSH',
                                    "protocol": 'TCP',
                                    "startport": 22,
                                    "endport": 22,
                                    "cidrlist": '0.0.0.0/0',
                        },
                        # Cent OS 5.3 (64 bit)
                        "sleep": 60,
                        "ostype": 'CentOS 5.3 (64-bit)',
                        "timeout": 10,
                        "mode": 'advanced',
                    }


class TestResourceTags(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):
        cls.api_client = super(
                               TestResourceTags,
                               cls
                               ).getClsTestClient().getApiClient()
        cls.services = Services().services
        # Get Zone
        cls.zone = get_zone(cls.api_client, cls.services)

        # Create domains, account etc.
        cls.domain = get_domain(cls.api_client, cls.services)

        cls.account = Account.create(
                            cls.api_client,
                            cls.services["account"],
                            admin=True,
                            )
        cls.zone = get_zone(cls.api_client, cls.services)

        cls.template = get_template(
                            cls.api_client,
                            cls.zone.id,
                            cls.services["ostype"]
                            )

        # Create service offerings, disk offerings etc
        cls.service_offering = ServiceOffering.create(
                                    cls.api_client,
                                    cls.services["service_offering"]
                                    )

        cls.disk_offering = DiskOffering.create(
                                    cls.api_client,
                                    cls.services["disk_offering"]
                                    )
        
        cls.services["iso"]["zoneid"] = cls.zone.id
        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
        cls.services["virtual_machine"]["template"] = cls.template.id
        cls.vm_1 = VirtualMachine.create(
                                    cls.api_client,
                                    cls.services["virtual_machine"],
                                    accountid=cls.account.name,
                                    domainid=cls.account.domainid,
                                    serviceofferingid=cls.service_offering.id,
                                    mode=cls.zone.networktype
                                )
        cls.vm_2 = VirtualMachine.create(
                                    cls.api_client,
                                    cls.services["virtual_machine"],
                                    accountid=cls.account.name,
                                    domainid=cls.account.domainid,
                                    serviceofferingid=cls.service_offering.id,
                                    mode=cls.zone.networktype
                                )
        cls._cleanup = [
                        cls.account,
                        cls.service_offering,
                        cls.disk_offering
                        ]
        return

    @classmethod
    def tearDownClass(cls):
        try:
            #Cleanup resources used
            print("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 = []
        self.rm_tags = []
        return

    def tearDown(self):
        try:
            #Clean up, terminate the created accounts, domains etc
            cleanup_resources(self.apiclient, self.cleanup)
        except Exception as e:
            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']})

        return
    
    @attr(tags=["advanced"])
    def test_01_lbrule_tag(self):
        """ Test Create tag on LB rule and remove the LB rule
        """
        # Validate the following
        # 1. Configured LB rule by assigning 2vms
        # 2. Create Tag on LB rule using CreateTag API
        # 3. Delete the LB rule

        self.debug("Fetching the network details for account: %s" %
                                                self.account.name)
        networks = Network.list(
                                self.apiclient,
                                account=self.account.name,
                                domainid=self.account.domainid,
                                listall=True
                                )
        self.assertEqual(
                         isinstance(networks, list),
                         True,
                         "List networks should not return an empty response"
                         )
        network = networks[0]
        self.debug("Network for the account: %s is %s" %
                                    (self.account.name, network.name))

        self.debug("Associating public IP for network: %s" % network.id)
        public_ip = PublicIPAddress.create(
                                    self.apiclient,
                                    accountid=self.account.name,
                                    zoneid=self.zone.id,
                                    domainid=self.account.domainid,
                                    networkid=network.id
                                    )
        self.cleanup.append(public_ip)

        self.debug("Trying to create LB rule on IP: %s" %
                                    public_ip.ipaddress.ipaddress)

        # Create Load Balancer rule on the public ip
        lb_rule = LoadBalancerRule.create(
                                    self.apiclient,
                                    self.services["lbrule"],
                                    ipaddressid=public_ip.ipaddress.id,
                                    accountid=self.account.name
                                    )

        # Check if the LB rule created successfully
        lb_rules = LoadBalancerRule.list(
                                         self.apiclient,
                                         id=lb_rule.id
                                         )

        self.assertEqual(
                         isinstance(lb_rules, list),
                         True,
                         "List LB rules should return valid list"
                         )

        self.debug("Assigning the virtual machines (%s, %s) to lb rule: %s" %
                                                        (self.vm_1.name,
                                                         self.vm_2.name,
                                                         lb_rule.name))

        lb_rule.assign(self.apiclient, [self.vm_1, self.vm_2])
        self.debug("Creating a tag for load balancer rule")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=lb_rule.id,
                         resourceType='LoadBalancer',
                         tags={'LB': 40}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='LoadBalancer',
                        key='LB',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        value=40
                        )

        self.debug("Tag created: %s" % str(tags))
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        self.assertEqual(
                         int(tags[0].value),
                         40,
                         "The tag value should match with the original value"
                         )
    
        lb_rules = LoadBalancerRule.list(
                                         self.apiclient,
                                         listall=True,
                                         key='FW',
                                         value=40
                                         )

        self.assertEqual(
                         isinstance(lb_rules, list),
                         True,
                         "List LB rules should return valid list"
                         )

        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=lb_rule.id,
                       resourceType='LoadBalancer',
                       tags={'LB': 40}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='LoadBalancer',
                        key='LB',
                        account=self.account.name,
                        domainid=self.account.domainid
                        )

        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )

        self.debug("Deleting the Load balancer rule")
        try:
            lb_rule.delete(self.apiclient)
        except Exception as e:
            self.fail("failed to delete load balancer rule! - %s" % e)
        return

    @attr(tags=["advanced"])
    def test_02_natrule_tag(self):
        """ Test Create tag on nat rule and remove the nat rule
        """
        # Validate the following
        # 1. Configured PF rule
        # 2. create Tag on PF rule  using CreateTag API
        # 3. Delete the PF rule

        self.debug("Fetching the network details for account: %s" %
                                                self.account.name)
        networks = Network.list(
                                self.apiclient,
                                account=self.account.name,
                                domainid=self.account.domainid,
                                listall=True
                                )
        self.assertEqual(
                         isinstance(networks, list),
                         True,
                         "List networks should not return an empty response"
                         )
        network = networks[0]
        self.debug("Network for the account: %s is %s" %
                                    (self.account.name, network.name))

        self.debug("Associating public IP for network: %s" % network.id)
        public_ip = PublicIPAddress.create(
                                    self.apiclient,
                                    accountid=self.account.name,
                                    zoneid=self.zone.id,
                                    domainid=self.account.domainid,
                                    networkid=network.id
                                    )
        self.cleanup.append(public_ip)

        self.debug("Trying to create LB rule on IP: %s" %
                                    public_ip.ipaddress.ipaddress)

        self.debug("Creating PF rule for vm: %s on Ip: %s" %
                            (self.vm_1.name, public_ip.ipaddress.ipaddress))

        nat_rule = NATRule.create(
                         self.apiclient,
                         self.vm_1,
                         self.services["natrule"],
                         ipaddressid=public_ip.ipaddress.id
                      )

        # Check if NAT rule created successfully
        nat_rules = NATRule.list(
                                 self.apiclient,
                                 id=nat_rule.id
                                 )

        self.assertEqual(
                         isinstance(nat_rules, list),
                         True,
                         "List NAT rules should return valid list"
                         )

        self.debug("Creating a tag for port forwarding rule")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=nat_rule.id,
                         resourceType='portForwardingRule',
                         tags={'PF': 40}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='portForwardingRule',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='PF',
                        value=40
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        self.assertEqual(
                         int(tags[0].value),
                         40,
                         "The tag value should match with the original value"
                         )
        
        nat_rules = NATRule.list(
                                 self.apiclient,
                                 listall=True,
                                 key='FW',
                                 value=40
                                )

        self.assertEqual(
                         isinstance(nat_rules, list),
                         True,
                         "List NAT rules should return valid list"
                         )
    
        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=nat_rule.id,
                       resourceType='portForwardingRule',
                       tags={'PF': 40}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='portForwardingRule',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='PF',
                        value=40
                        )

        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )
        self.debug("Deleting the port forwarding rule")
        try:
            nat_rule.delete(self.apiclient)
        except Exception as e:
            self.fail("failed to delete port forwarding rule! - %s" % e)
        return

    @attr(tags=["advanced"])
    def test_03_firewallrule_tag(self):
        """ Test Create tag on firewall rule and remove the firewall rule
        """
        # Validate the following
        # 1. Configured firewall rule
        # 2. create Tag on firewall rule  using CreateTag API
        # 3. Delete the firewall rule

        self.debug("Fetching the network details for account: %s" %
                                                self.account.name)
        networks = Network.list(
                                self.apiclient,
                                account=self.account.name,
                                domainid=self.account.domainid,
                                listall=True
                                )
        self.assertEqual(
                         isinstance(networks, list),
                         True,
                         "List networks should not return an empty response"
                         )
        network = networks[0]
        self.debug("Network for the account: %s is %s" %
                                    (self.account.name, network.name))

        self.debug("Associating public IP for network: %s" % network.id)
        public_ip = PublicIPAddress.create(
                                    self.apiclient,
                                    accountid=self.account.name,
                                    zoneid=self.zone.id,
                                    domainid=self.account.domainid,
                                    networkid=network.id
                                    )
        self.cleanup.append(public_ip)

        self.debug("Creating firewall rule on public IP: %s" %
                                                public_ip.ipaddress.ipaddress)
        # Create Firewall rule on public IP
        fw_rule = FireWallRule.create(
                            self.apiclient,
                            ipaddressid=public_ip.ipaddress.id,
                            protocol='TCP',
                            cidrlist=[self.services["fw_rule"]["cidr"]],
                            startport=self.services["fw_rule"]["startport"],
                            endport=self.services["fw_rule"]["endport"]
                            )

        self.debug("Created firewall rule: %s" % fw_rule.id)

        fw_rules = FireWallRule.list(
                                     self.apiclient,
                                     id=fw_rule.id
                                    )
        self.assertEqual(
                         isinstance(fw_rules, list),
                         True,
                         "List fw rules should return a valid firewall rules"
                         )

        self.assertNotEqual(
                            len(fw_rules),
                            0,
                            "Length of fw rules response should not be zero"
                            )

        self.debug("Creating a tag for firewall rule")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=fw_rule.id,
                         resourceType='FirewallRule',
                         tags={'FW': '40'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='FirewallRule',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='FW',
                        value='40'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        
        self.assertEqual(
                         tags[0].value,
                         '40',
                         "The tag value should match with the original value"
                         )

        fw_rules = FireWallRule.list(
                                     self.apiclient,
                                     listall=True,
                                     key='FW',
                                     value='40'
                                    )
        self.assertEqual(
                         isinstance(fw_rules, list),
                         True,
                         "List fw rules should return a valid firewall rules"
                         )

        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=fw_rule.id,
                       resourceType='FirewallRule',
                       tags={'FW': '40'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='FirewallRule',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='FW',
                        value='40'
                        )

        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )

        self.debug("Deleting the firewall rule")
        try:
            fw_rule.delete(self.apiclient)
        except Exception as e:
            self.fail("failed to delete firewall rule! - %s" % e)
        return

    @attr(tags=["advanced"])
    def test_04_vpn_tag(self):
        """ Test Create tag on vpn and remove the vpn
        """
        # Validate the following
        # 1. Enable the VPN
        # 2. create Tag on VPN rule using CreateTag API
        # 3. Delete the VPN rule
        self.skipTest("VPN resource tags are unsupported in 4.0")

        self.debug("Fetching the network details for account: %s" %
                                                self.account.name)
        networks = Network.list(
                                self.apiclient,
                                account=self.account.name,
                                domainid=self.account.domainid,
                                listall=True
                                )
        self.assertEqual(
                         isinstance(networks, list),
                         True,
                         "List networks should not return an empty response"
                         )
        network = networks[0]
        self.debug("Network for the account: %s is %s" %
                                    (self.account.name, network.name))

        self.debug("Associating public IP for network: %s" % network.id)
        public_ip = PublicIPAddress.create(
                                    self.apiclient,
                                    accountid=self.account.name,
                                    zoneid=self.zone.id,
                                    domainid=self.account.domainid,
                                    networkid=network.id
                                    )
        self.cleanup.append(public_ip)

        nat_rule = NATRule.create(
                         self.apiclient,
                         self.vm_1,
                         self.services["natrule"],
                         ipaddressid=public_ip.ipaddress.id
                      )

        # Check if NAT rule created successfully
        nat_rules = NATRule.list(
                                 self.apiclient,
                                 id=nat_rule.id
                                 )

        self.assertEqual(
                         isinstance(nat_rules, list),
                         True,
                         "List NAT rules should return valid list"
                         )

        # User should be able to enable VPN on source NAT
        self.debug("Creating VPN with public NAT IP: %s" %
                                            public_ip.ipaddress.ipaddress)
        # Assign VPN to source NAT
        try:
            vpn = Vpn.create(
                        self.apiclient,
                        public_ip.ipaddress.id,
                        account=self.account.name,
                        domainid=self.account.domainid
                        )

        except Exception as e:
            print e

        vpns = Vpn.list(
                        self.apiclient,
                        publicipid=public_ip.ipaddress.id,
                        listall=True,
                        )

        self.assertEqual(
                         isinstance(vpns, list),
                         True,
                         "List VPNs should return a valid VPN list"
                         )

        self.assertNotEqual(
                            len(vpns),
                            0,
                            "Length of list VPN response should not be zero"
                            )

        self.debug("Creating a tag for VPN rule")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=nat_rule.id,
                         resourceType='VPN',
                         tags={'protocol': 'L2TP'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='VPN',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='protocol',
                        value='L2TP'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        self.assertEqual(
                         tags[0].value,
                         'L2TP',
                         "The tag value should match with the original value"
                         )
        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=vpn.id,
                       resourceType='VPN',
                       tags={'protocol': 'L2TP'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='VPN',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='protocol',
                        value='L2TP'
                        )

        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )

        self.debug("Disabling the VPN")
        try:
            vpn.delete(self.apiclient)
        except Exception as e:
            self.fail("failed to disable VPN! - %s" % e)
        return

    @attr(tags=["advanced", "basic"])
    def test_05_vm_tag(self):
        """ Test creation, listing and deletion tags on UserVM
        """
        # Validate the following
        # 1. Create  a tag on VM using createTags API
        # 2. Delete above created tag using deleteTags API

        self.debug("Creating a tag for user VM")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=self.vm_1.id,
                         resourceType='userVM',
                         tags={'region': 'India'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='userVM',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        self.assertEqual(
                         tags[0].value,
                         'India',
                         "The tag value should match with the original value"
                         )
        
        vms = VirtualMachine.list(
                                    self.apiclient,
                                    listall=True,
                                    key='region',
                                    value='India'
                                  )
    
        self.assertEqual(
                         isinstance(vms, list),
                         True,
                         "Tag based VMs listing failed")
    
        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=self.vm_1.id,
                       resourceType='userVM',
                       tags={'region': 'India'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='userVM',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )
        return

    @attr(tags=["advanced", "basic"])
    def test_06_template_tag(self):
        """ Test creation, listing and deletion tag on templates
        """
        # Validate the following
        # 1. Create a tag on template/ISO using createTags API
        # 2. Delete above created tag using deleteTags API

        self.debug("Stopping the virtual machine: %s" % self.vm_1.name)
        #Stop virtual machine
        self.vm_1.stop(self.apiclient)

        timeout = self.services["timeout"]
        #Wait before server has be successfully stopped
        time.sleep(self.services["sleep"])

        while True:
            list_volume = Volume.list(
                                   self.apiclient,
                                   virtualmachineid=self.vm_1.id,
                                   type='ROOT',
                                   listall=True
                                   )
            if isinstance(list_volume, list):
                break
            elif timeout == 0:
                raise Exception("List volumes failed.")

            time.sleep(5)
            timeout = timeout - 1

        self.volume = list_volume[0]

        self.debug("Creating template from ROOT disk of virtual machine: %s" %
                                                            self.vm_1.name)
        #Create template from volume
        template = Template.create(
                                    self.apiclient,
                                    self.services["template"],
                                    self.volume.id
                                )
        self.cleanup.append(template)
        self.debug("Created the template(%s). Now restarting the userVm: %s" %
                                            (template.name, self.vm_1.name))
        self.vm_1.start(self.apiclient)

        self.debug("Creating a tag for the template")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=template.id,
                         resourceType='Template',
                         tags={'OS': 'CentOS'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='Template',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='OS',
                        value='CentOS'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        self.assertEqual(
                         tags[0].value,
                         'CentOS',
                         'The tag should have original value'
                         )
      
        templates = Template.list(
                  self.apiclient,
                  templatefilter=\
                  self.services["template"]["templatefilter"],  
                  listall=True,
                  key='OS',
                  value='CentOS'
                  )

        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=template.id,
                       resourceType='Template',
                       tags={'OS': 'CentOS'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='Template',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='OS',
                        value='CentOS'
                        )
        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )
        return

    @attr(tags=["advanced", "basic"])
    def test_07_iso_tag(self):
        """ Test creation, listing and deletion tags on ISO
        """
        # Validate the following
        # 1. Create  a tag on ISO using createTags API
        # 2. Delete above created tag using deleteTags API

        iso = Iso.create(
                         self.apiclient,
                         self.services["iso"],
                         account=self.account.name,
                         domainid=self.account.domainid
                         )
        self.debug("ISO created with ID: %s" % iso.id)

        list_iso_response = list_isos(
                                      self.apiclient,
                                      id=iso.id
                                      )
        self.assertEqual(
                         isinstance(list_iso_response, list),
                         True,
                         "Check list response returns a valid list"
                         )

        self.debug("Creating a tag for the ISO")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=iso.id,
                         resourceType='ISO',
                         tags={'OS': 'CentOS'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='ISO',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='OS',
                        value='CentOS'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        self.assertEqual(
                         tags[0].value,
                         'CentOS',
                         'The tag should have original value'
                         )
        isos = Iso.list(
                        self.apiclient,
                        key='OS',
                        value='CentOS',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        isofilter='all'
                    )

        self.assertEqual(
                         isinstance(isos, list),
                         True,
                         "List isos should not return an empty response"
                         )

        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=iso.id,
                       resourceType='ISO',
                       tags={'OS': 'CentOS'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='ISO',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='OS',
                        value='CentOS'
                        )
        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )
        return

    @attr(tags=["advanced", "basic"])
    def test_08_volume_tag(self):
        """ Test creation, listing and deletion tagson volume
        """
        # Validate the following
        # 1. Create a tag on volume using createTags API
        # 2. Delete above created tag using deleteTags API

        self.debug("Creating volume for account: %s " %
                                                self.account.name)
        volume = Volume.create(
                               self.apiclient,
                               self.services["volume"],
                               zoneid=self.zone.id,
                               account=self.account.name,
                               domainid=self.account.domainid,
                               diskofferingid=self.disk_offering.id
                               )
        self.cleanup.append(volume)

        self.debug("Volume created in account: %s" % volume.name)

        self.debug("Creating a tag for the volume")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=volume.id,
                         resourceType='volume',
                         tags={'region': 'India'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='volume',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        self.assertEqual(
                         tags[0].value,
                         'India',
                         'The tag should have original value'
                         )
        
        vols = Volume.list(self.apiclient,
                  listall=True,
                  key='region',
                  value='India'
                 )
        self.assertEqual(
                         isinstance(vols, list),
                         True,
                         "List volumes should not return empty response"
                        )
    
        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=volume.id,
                       resourceType='volume',
                       tags={'region': 'India'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='volume',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region'
                        )
        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )
        return

    @attr(tags=["advanced", "basic"])
    def test_09_snapshot_tag(self):
        """ Test creation, listing and deletion tag son snapshot
        """
        # Validate the following
        # 1. Create a tag on snapshot using createTags API
        # 2. Delete above created tag using deleteTags API

        self.debug("Creating snapshot on ROOT volume for VM: %s " %
                                                            self.vm_1.name)
        # Get the Root disk of VM
        volumes = list_volumes(
                               self.apiclient,
                               virtualmachineid=self.vm_1.id,
                               type='ROOT',
                               listall=True
                              )
        volume = volumes[0]

        # Create a snapshot from the ROOTDISK
        snapshot = Snapshot.create(self.apiclient, volume.id)
        self.debug("Snapshot created: ID - %s" % snapshot.id)
        self.cleanup.append(snapshot)

        snapshots = list_snapshots(
                                   self.apiclient,
                                   id=snapshot.id
                                   )
        self.assertEqual(
                         isinstance(snapshots, list),
                         True,
                         "Tag based snapshot listing failed")

        self.debug("Creating a tag for the snapshot")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=snapshot.id,
                         resourceType='snapshot',
                         tags={'type': 'manual'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='snapshot',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='type',
                        value='manual'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        self.assertEqual(
                         tags[0].value,
                         'manual',
                         'The tag should have original value'
                         )
        
        snapshots = list_snapshots(
                                   self.apiclient,
                                   listall=True,
                                   key='type',
                                   value='manual'
                                   )
        self.assertEqual(
                         isinstance(snapshots, list),
                         True,
                         "Check list response returns a valid list"
                         )
        self.assertNotEqual(
                            snapshots,
                            None,
                            "Check if result exists in list snapshots call"
                            )
        self.debug("Listing snapshots by tag was successful")

        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=snapshot.id,
                       resourceType='snapshot',
                       tags={'type': 'manual'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='snapshot',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='type',
                        value='manual'
                        )
        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )

        return

    @attr(tags=["advanced"])
    def test_10_network_tag(self):
        """ Testcreation, 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

        self.debug("Fetching the network details for account: %s" %
                                                self.account.name)
        networks = Network.list(
                                self.apiclient,
                                account=self.account.name,
                                domainid=self.account.domainid,
                                listall=True
                                )
        self.assertEqual(
                         isinstance(networks, list),
                         True,
                         "List networks should not return an empty response"
                         )
        network = networks[0]
        self.debug("Network for the account: %s is %s" %
                                    (self.account.name, network.name))

        self.debug("Creating a tag for load balancer rule")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=network.id,
                         resourceType='Network',
                         tags={'region': 'India'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='Network',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        self.assertEqual(
                         tags[0].value,
                         'India',
                         'The tag should have original value'
                         )
        
        networks = Network.list(
                                self.apiclient,
                                account=self.account.name,
                                domainid=self.account.domainid,
                                listall=True,
                                key='region',
                                value='India'       
                                )
        self.assertEqual(
                         isinstance(networks, list),
                         True,
                         "List networks should not return an empty response"
                         )

        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=network.id,
                       resourceType='Network',
                       tags={'region': 'India'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='Network',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )
        return

    @attr(tags=["basic", "sg"])
    def test_11_migrate_tagged_vm_del(self):
        """ Test migration of a tagged vm and delete the tag
        """
        # Validate the following
        # 1. Create a tag on VM using createTags API
        # 2. Delete above created tag using deleteTags API

        vms = VirtualMachine.list(
                                  self.apiclient,
                                  id=self.vm_1.id,
                                  listall=True
                                  )

        self.assertEqual(
                         isinstance(vms, list),
                         True,
                         "List vms should not return empty response"
                         )
        source_host = vms[0].hostid
    
        hosts = Host.list(
                          self.apiclient,
                          zoneid=self.zone.id,
                          resourcestate='Enabled',
                          type='Routing'
                          )
        self.assertEqual(
                         isinstance(hosts, list),
                         True,
                         "List hosts should return valid host response"
                         )

        self.debug("Available hosts: ")
        for host in hosts:
            self.debug("Host: %s" % host.id)

            # Filtering out the source host from list host response
            temp_hosts = [host for host in hosts if host.id != source_host]
            dest_host = temp_hosts[0]

            self.debug("Destination host is: %s" % dest_host.id)
            self.debug("Source host is: %s" % source_host)

        self.debug("Creating a tag for user VM")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=self.vm_1.id,
                         resourceType='userVM',
                         tags={'region': 'India'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='userVM',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )

        self.assertEqual(
                         tags[0].value,
                         'India',
                         'The tag should have original value'
                         )

        self.debug("Migrating the instance from: %s to %s" %
                                                (source_host, dest_host.id))
        self.vm_1.migrate(self.apiclient, hostid=dest_host.id)

        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=self.vm_1.id,
                       resourceType='userVM',
                       tags={'region': 'India'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='userVM',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )
        return

    @attr(tags=["advanced", "basic"])
    def test_13_tag_case_insensitive(self):
        """ Test to verify that tags are not case sensitive
        """
        # Validate the following
        # 1. Create a tag on VM using createTags API
        # 2. Add same tag in upper case.
        # 3. Verify that tag creation failed.

        self.debug("Creating a tag for user VM")
        tag_1 = Tag.create(
                         self.apiclient,
                         resourceIds=self.vm_1.id,
                         resourceType='userVM',
                         tags={'region': 'India'}
                         )
        self.debug("Tag created: %s" % tag_1.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='userVM',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )

        self.assertEqual(
                         tags[0].value,
                         'India',
                         'The tag should have original value'
                         )
        self.debug("Creating the same tag with caps for user VM")
        
        try:
            tag_2 = Tag.create(
                     self.apiclient,
                     resourceIds=self.vm_1.id,
                     resourceType='userVM',
                     tags={'REGION': 'INDIA'}
                )
        except Exception as e:
            pass
        else:
            assert("Creating same tag in upper case succeeded")

        self.debug("Deleting the created tag..")
        try:
            tag_1.delete(
                       self.apiclient,
                       resourceIds=self.vm_1.id,
                       resourceType='userVM',
                       tags={'region': 'India'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='userVM',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )

        return

    @attr(tags=["advanced", "basic"])
    def test_14_special_char_mutiple_tags(self):
        """ Test multiple tags and with special characters on same machine
        """
        # Validate the following
        # 1. Create more than 10 tags to VM using createTags API
        # 2. Create a tag with special characters on VM using createTags API

        self.debug("Creating a tag for user VM")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=self.vm_1.id,
                         resourceType='userVM',
                         tags={
                                    'region': 'India',
                                    'offering': 'high',
                                    'type': 'webserver',
                                    'priority': 'critical',
                                    'networking': 'advanced',
                                    'os': 'centos',
                                    'backup': 'no$required',
                                    'rootvolume': 'NFS',
                                    'iso': 'na',
                                    'ha': 'yes',
                                    'test': 'test'
                               }
                         )
        self.debug("Tags created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='userVM',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        self.assertEqual(
                         tags[0].value,
                         'India',
                         'The tag should have original value'
                         )
        # Cleanup
        tag.delete(
                       self.apiclient,
                       resourceIds=self.vm_1.id,
                       resourceType='userVM',
                       tags={
                             'region': 'India',
                             'offering': 'high',
                             'type': 'webserver',
                             'priority': 'critical',
                             'networking': 'advanced',
                             'os': 'centos',
                             'backup': 'no$required',
                             'rootvolume': 'NFS',
                             'iso': 'na',
                             'ha': 'yes',
                             'test': 'test'
                             }
                       )
        return

    @attr(tags=["advanced"])
    def test_15_project_tag(self):
        """ Test creation, listing and deletion tags on projects
        """
        # Validate the following
        # 1. Create a new project 
        # 2. Create a tag on projects using createTags API
        # 3. Delete the tag.

        # Create project as a domain admin
        project = Project.create(
                                 self.apiclient,
                                 self.services["project"],
                                 account=self.account.name,
                                 domainid=self.account.domainid
                                 )
        # Cleanup created project at end of test
        self.cleanup.append(project)
        self.debug("Created project with domain admin with ID: %s" %
                                                                project.id)

        self.debug("Creating a tag for the project")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=project.id,
                         resourceType='project',
                         tags={'region': 'India'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='project',
                        projectid=project.id,
                        key='region',
                        )
        self.debug("tags = %s" % tags)
 
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        self.assertEqual(
                         tags[0].value,
                         'India',
                         'The tag should have original value'
                         )
    
        projects = Project.list(
                             self.apiclient,
                             listall=True,
                             key='region',
                             value='India'
                            )

        self.assertEqual(
                         isinstance(projects, list),
                         True,
                         "List Project should return valid list"
                         )


        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=project.id,
                       resourceType='project',
                       tags={'region': 'India'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='project',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )
        return

    @attr(tags=["advanced", "basic"])
    def test_16_query_tags_other_account(self):
        """ Test Query the tags from other account
        """
        # Validate the following
        # 1. Login with an account(account A)
        # 2. Create a tags on resource(eg:VM)
        # 3. Login with other account and query the tags using
        #    listTags API

        self.debug("Creating user accounts..")

        user_account = Account.create(
                            self.apiclient,
                            self.services["user"],
                            domainid=self.domain.id
                            )
        self.cleanup.append(user_account)
        
        other_user_account = Account.create(
                            self.apiclient,
                            self.services["other_user"],
                            domainid=self.domain.id
                            )
        self.cleanup.append(other_user_account)
    
        iso = Iso.create(
                         self.apiclient,
                         self.services["iso"],
                         account=user_account.name,
                         domainid=user_account.domainid
                         )
        self.debug("ISO created with ID: %s" % iso.id)

        list_iso_response = list_isos(
                                      self.apiclient,
                                      id=iso.id
                                      )
        self.assertEqual(
                            isinstance(list_iso_response, list),
                            True,
                            "Check list response returns a valid list"
                        )

        self.debug("Creating a tag for the ISO")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=iso.id,
                         resourceType='ISO',
                         tags={'region': 'India'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='ISO',
                        account=user_account.name,
                        domainid=user_account.domainid,
                        key='region',
                        )
    
        self.debug("Verify listTag API using user account")
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        self.assertEqual(
                         tags[0].value,
                         'India',
                         "The tag value should match with the original value"
                         )
 
        self.debug("Verify listTag API using other account")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='ISO',
                        account=other_user_account.name,
                        domainid=other_user_account.domainid,
                        key='region',
                        )
        
        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                        )
        
        return

    @attr(tags=["advanced", "basic"])
    def test_17_query_tags_admin_account(self):
        """ Test Query the tags from admin account
        """
        # Validate the following
        # 1. Login with an account(account A)
        # 2. Create a tags on resource(eg:VM)
        # 3. Login with admin account and query the tags using
        #    listTags API

        self.debug("Creating user accounts..")

        user_account = Account.create(
                            self.apiclient,
                            self.services["user"],
                            domainid=self.domain.id
                            )
        self.cleanup.append(user_account)
        
        iso = Iso.create(
                         self.apiclient,
                         self.services["iso"],
                         account=user_account.name,
                         domainid=user_account.domainid
                         )
        self.debug("ISO created with ID: %s" % iso.id)

        list_iso_response = list_isos(
                                      self.apiclient,
                                      id=iso.id
                                      )
        self.assertEqual(
                         isinstance(list_iso_response, list),
                         True,
                         "Check list response returns a valid list"
                         )

        self.debug("Creating a tag for the ISO")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=iso.id,
                         resourceType='ISO',
                         tags={'region': 'India'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='ISO',
                        account=user_account.name,
                        domainid=user_account.domainid,
                        key='region',
                        )
    
        self.debug("Verify listTag API using user account")
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        self.assertEqual(
                         tags[0].value,
                         'India',
                         "The tag value should match with the original value"
                         )
 
        self.debug("Verify listTag API using admin account")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='ISO',
                        key='region',
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                        )
        self.assertEqual(
                         tags[0].value,
                         'India',
                         'The tag should have original value'
                        )
        
        return

    @attr(tags=["advanced", "basic", "simulator"])
    def test_18_invalid_list_parameters(self):
        """ Test listAPI with invalid tags parameter
        """
        # Validate the following
        # 1. Create a tag on  supported resource type(ex:vms)
        # 2. Run the list API commands  with passing invalid key parameter

        self.debug("Creating a tag for user VM")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=self.vm_1.id,
                         resourceType='userVM',
                         tags={'region': 'India'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        # Add tag for removal during teardown. vm_1 is shared resource if it is tagged
        # and the test fails with exception then the tag is not deleted. And
        # subsequent tests fail to tag the vm_1 with same key-pair
        # breaking the tests.   
        self.rm_tags.append({'tag_obj': tag,'restype': 'userVM', 'resid': self.vm_1.id,
                 'key': 'region', 'value': 'India'})

        self.debug("Passing invalid key parameter to the listAPI for vms")

        vms = VirtualMachine.list(self.apiclient,
            **{'tags[0].key': 'region111',
             'tags[0].value': 'India',
             'listall' : 'True'}
        )
        self.assertEqual(
                         vms,
                         None,
                         "List vms should return empty response"
                        )

        return

    @attr(tags=["advanced", "basic"])
    def test_19_delete_add_same_tag(self):
        """ Test deletion and addition of same tag on a resource.
        """

        # Validate the following
        # 1. Deletion of a tag without any errors.
        # 2. 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'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='userVM',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )

        self.assertEqual(
                         tags[0].value,
                         "India",
                         "Tag created with incorrect value"
                         )

        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=self.vm_1.id,
                       resourceType='userVM',
                       tags={'region': 'India'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='userVM',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )
        self.debug("Recreating the tag with same name")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=self.vm_1.id,
                         resourceType='userVM',
                         tags={'region': 'India'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='userVM',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                            )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )

        self.assertEqual(tags[0].value,
                         "India",
                         "Tag created with incorrect value"
                         )
    
        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=self.vm_1.id,
                       resourceType='userVM',
                       tags={'region': 'India'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)
        return

    @attr(tags=["advanced", "basic"])
    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)
        volume = Volume.create(
                               self.apiclient,
                               self.services["volume"],
                               zoneid=self.zone.id,
                               account=self.account.name,
                               domainid=self.account.domainid,
                               diskofferingid=self.disk_offering.id
                               )
        self.cleanup.append(volume)

        self.debug("Volume created in account: %s" % volume.name)

        self.debug("Creating a tag for the volume")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=volume.id,
                         resourceType='volume',
                         tags={'region': 'India'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='volume',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )
        self.assertEqual(
                         tags[0].value,
                         'India',
                         'The tag should have original value'
                         )
 
        self.debug("Creating a tag for user VM")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=self.vm_1.id,
                         resourceType='userVM',
                         tags={'region': 'India'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='userVM',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )

        self.assertEqual(
                         tags[0].value,
                         "India",
                         "Tag created with incorrect value"
                         )
    
        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=self.vm_1.id,
                       resourceType='userVM',
                       tags={'region': 'India'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        self.debug("Verifying if tag is actually deleted!")
        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='userVM',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         tags,
                         None,
                         "List tags should return empty response"
                         )

        return

    @attr(tags=["advanced", "basic"])
    def test_21_create_tag_stopped_vm(self):
        "Test creation of tag on stopped vm."

        self.debug("Stopping the virtual machine: %s" % self.vm_1.name)
        #Stop virtual machine
        self.vm_1.stop(self.apiclient)
    
        timeout = self.services["timeout"]
        #Wait before server has be successfully stopped
        time.sleep(self.services["sleep"])

        list_vm_response = list_virtual_machines(
                                                 self.apiclient,
                                                 id=self.vm_1.id
                                                 )

        self.debug(
                "Verify listVirtualMachines response for virtual machine: %s" \
                % self.vm_1.id
          )

        self.assertEqual(
                         isinstance(list_vm_response, list),
                         True,
                         "Check list response returns a valid list"
                         )
        vm_response = list_vm_response[0]

        self.assertEqual(
                         vm_response.state,
                         "Stopped",
                         "VM should be in stopped state after deployment"
                         )

        self.debug("Creating a tag for user VM")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=self.vm_1.id,
                         resourceType='userVM',
                         tags={'region': 'India'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='userVM',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )

        self.assertEqual(
                         tags[0].value,
                         "India",
                         "Tag created with incorrect value"
                         )

        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=self.vm_1.id,
                       resourceType='userVM',
                       tags={'region': 'India'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)
        return

    @attr(tags=["advanced", "basic"])
    def test_22_create_tag_destroyed_vm(self):
        "Test creation of tag on stopped vm."

        self.debug("Destroying instance: %s" % self.vm_1.name)
        self.vm_1.delete(self.apiclient)

        self.debug("Creating a tag for user VM")
        tag = Tag.create(
                         self.apiclient,
                         resourceIds=self.vm_1.id,
                         resourceType='userVM',
                         tags={'region': 'India'}
                         )
        self.debug("Tag created: %s" % tag.__dict__)

        tags = Tag.list(
                        self.apiclient,
                        listall=True,
                        resourceType='userVM',
                        account=self.account.name,
                        domainid=self.account.domainid,
                        key='region',
                        value='India'
                        )
        self.assertEqual(
                         isinstance(tags, list),
                         True,
                         "List tags should not return empty response"
                         )

        self.assertEqual(
                         tags[0].value,
                         "India",
                         "Tag created with incorrect value"
                         )

        self.debug("Deleting the created tag..")
        try:
            tag.delete(
                       self.apiclient,
                       resourceIds=self.vm_1.id,
                       resourceType='userVM',
                       tags={'region': 'India'}
                       )
        except Exception as e:
            self.fail("Failed to delete the tag - %s" % e)

        return
