cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tall...@apache.org
Subject [2/3] git commit: updated refs/heads/master to ada8cdc
Date Fri, 13 Feb 2015 10:34:10 GMT
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ada8cdce/test/integration/testpaths/testpath_usage.py
----------------------------------------------------------------------
diff --git a/test/integration/testpaths/testpath_usage.py b/test/integration/testpaths/testpath_usage.py
new file mode 100644
index 0000000..17d56cc
--- /dev/null
+++ b/test/integration/testpaths/testpath_usage.py
@@ -0,0 +1,3327 @@
+# 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.
+""" Test cases for Usage Test Path
+"""
+from nose.plugins.attrib import attr
+from marvin.cloudstackTestCase import cloudstackTestCase, unittest
+from marvin.lib.utils import (cleanup_resources,
+                              validateList,
+                              verifyRouterState,
+                              get_process_status)
+from marvin.lib.base import (Account,
+                             ServiceOffering,
+                             VirtualMachine,
+                             Template,
+                             Iso,
+                             DiskOffering,
+                             Volume,
+                             Snapshot,
+                             PublicIPAddress,
+                             LoadBalancerRule,
+                             EgressFireWallRule,
+                             Router,
+                             VmSnapshot,
+                             Usage,
+                             Configurations,
+                             FireWallRule,
+                             NATRule,
+                             StaticNATRule,
+                             Network,
+                             Vpn,
+                             VpnUser,
+                             VpcOffering,
+                             VPC,
+                             NetworkACL)
+from marvin.lib.common import (get_domain,
+                               get_zone,
+                               get_template,
+                               createEnabledNetworkOffering,
+                               get_builtin_template_info,
+                               findSuitableHostForMigration,
+                               list_hosts,
+                               list_routers)
+from marvin.codes import (PASS, FAIL, ERROR_NO_HOST_FOR_MIGRATION)
+from marvin.sshClient import SshClient
+import time
+
+
+def CreateEnabledNetworkOffering(apiclient, networkServices):
+    """Create network offering of given services and enable it"""
+
+    result = createEnabledNetworkOffering(apiclient, networkServices)
+    assert result[0] == PASS,\
+        "Network offering creation/enabling failed due to %s" % result[2]
+    return result[1]
+
+
+class TestUsage(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        testClient = super(TestUsage, cls).getClsTestClient()
+        cls.hypervisor = testClient.getHypervisorInfo()
+        cls.apiclient = testClient.getApiClient()
+        cls.testdata = testClient.getParsedTestDataConfig()
+
+        # Get Zone, Domain and templates
+        cls.domain = get_domain(cls.apiclient)
+        cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
+
+        cls.mgtSvrDetails = cls.config.__dict__["mgtSvr"][0].__dict__
+
+        isUsageJobRunning = cls.IsUsageJobRunning()
+        if not isUsageJobRunning:
+            raise unittest.SkipTest("Skipping, usage job is not running")
+
+        if cls.testdata["configurableData"][
+                "setUsageConfigurationThroughTestCase"]:
+            cls.setUsageConfiguration()
+            cls.RestartServers()
+
+        cls.hypervisor = testClient.getHypervisorInfo()
+
+        cls.template = get_template(
+            cls.apiclient,
+            cls.zone.id,
+            cls.testdata["ostype"])
+        cls._cleanup = []
+
+        try:
+            # If local storage is enabled, alter the offerings to use
+            # localstorage
+            if cls.zone.localstorageenable:
+                cls.testdata["service_offering"]["storagetype"] = 'local'
+
+            # Create 2 service offerings with different values for
+            # for cpunumber, cpuspeed, and memory
+
+            cls.testdata["service_offering"]["cpunumber"] = "1"
+            cls.testdata["service_offering"]["cpuspeed"] = "128"
+            cls.testdata["service_offering"]["memory"] = "256"
+
+            cls.service_offering = ServiceOffering.create(
+                cls.apiclient,
+                cls.testdata["service_offering"]
+            )
+            cls._cleanup.append(cls.service_offering)
+
+            cls.testdata["service_offering"]["cpunumber"] = "2"
+            cls.testdata["service_offering"]["cpuspeed"] = "256"
+            cls.testdata["service_offering"]["memory"] = "512"
+
+            cls.service_offering_2 = ServiceOffering.create(
+                cls.apiclient,
+                cls.testdata["service_offering"]
+            )
+            cls._cleanup.append(cls.service_offering_2)
+
+            # Create isolated network offering
+            cls.isolated_network_offering = CreateEnabledNetworkOffering(
+                cls.apiclient,
+                cls.testdata["isolated_network_offering"]
+            )
+            cls._cleanup.append(cls.isolated_network_offering)
+
+            cls.isolated_network_offering_2 = CreateEnabledNetworkOffering(
+                cls.apiclient,
+                cls.testdata["isolated_network_offering"]
+            )
+            cls._cleanup.append(cls.isolated_network_offering_2)
+
+            cls.isolated_network_offering_vpc = CreateEnabledNetworkOffering(
+                cls.apiclient,
+                cls.testdata["nw_offering_isolated_vpc"]
+            )
+            cls._cleanup.append(cls.isolated_network_offering_vpc)
+
+            cls.testdata["shared_network_offering_all_services"][
+                "specifyVlan"] = "True"
+            cls.testdata["shared_network_offering_all_services"][
+                "specifyIpRanges"] = "True"
+
+            cls.shared_network_offering = CreateEnabledNetworkOffering(
+                cls.apiclient,
+                cls.testdata["shared_network_offering_all_services"]
+            )
+            cls._cleanup.append(cls.shared_network_offering)
+
+            configs = Configurations.list(
+                cls.apiclient,
+                name='usage.stats.job.aggregation.range'
+            )
+
+            # Set the value for one more minute than
+            # actual range to be on safer side
+            cls.usageJobAggregationRange = (
+                int(configs[0].value) + 1) * 60  # in seconds
+        except Exception as e:
+            cls.tearDownClass()
+            raise e
+        return
+
+    @classmethod
+    def tearDownClass(cls):
+        try:
+            cleanup_resources(cls.apiclient, cls._cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.dbclient = self.testClient.getDbConnection()
+        self.cleanup = []
+        # Create an account
+        self.account = Account.create(
+            self.apiclient,
+            self.testdata["account"],
+            domainid=self.domain.id
+        )
+        self.cleanup.append(self.account)
+        # Create user api client of the account
+        self.userapiclient = self.testClient.getUserApiClient(
+            UserName=self.account.name,
+            DomainName=self.account.domain
+        )
+
+    def tearDown(self):
+        try:
+            cleanup_resources(self.apiclient, self.cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    @classmethod
+    def setUsageConfiguration(cls):
+        """ Set the configuration parameters so that usage job runs
+            every 10 miuntes """
+
+        Configurations.update(
+            cls.apiclient,
+            name="enable.usage.server",
+            value="true"
+        )
+
+        Configurations.update(
+            cls.apiclient,
+            name="usage.aggregation.timezone",
+            value="GMT"
+        )
+
+        Configurations.update(
+            cls.apiclient,
+            name="usage.execution.timezone",
+            value="GMT"
+        )
+
+        Configurations.update(
+            cls.apiclient,
+            name="usage.stats.job.aggregation.range",
+            value="10"
+        )
+
+        currentMgtSvrTime = cls.getCurrentMgtSvrTime()
+        dateTimeSplit = currentMgtSvrTime.split("/")
+        cls.curDate = dateTimeSplit[0]
+        timeSplit = dateTimeSplit[1].split(":")
+        minutes = int(timeSplit[1])
+        minutes += 5
+        usageJobExecTime = timeSplit[0] + ":" + str(minutes)
+
+        Configurations.update(
+            cls.apiclient,
+            name="usage.stats.job.exec.time",
+            value=usageJobExecTime
+        )
+
+        return
+
+    @classmethod
+    def getCurrentMgtSvrTime(cls, format='%Y-%m-%d/%H:%M'):
+        """ Get the current time from Management Server """
+
+        sshClient = SshClient(
+            cls.mgtSvrDetails["mgtSvrIp"],
+            22,
+            cls.mgtSvrDetails["user"],
+            cls.mgtSvrDetails["passwd"]
+        )
+        command = "date +%s" % format
+        return sshClient.execute(command)[0]
+
+    @classmethod
+    def RestartServers(cls):
+        """ Restart management server and usage server """
+
+        sshClient = SshClient(
+            cls.mgtSvrDetails["mgtSvrIp"],
+            22,
+            cls.mgtSvrDetails["user"],
+            cls.mgtSvrDetails["passwd"]
+        )
+        command = "service cloudstack-management restart"
+        sshClient.execute(command)
+
+        command = "service cloudstack-usage restart"
+        sshClient.execute(command)
+        return
+
+    @classmethod
+    def IsUsageJobRunning(cls):
+        """ Check that usage job is running on Management server or not"""
+
+        sshClient = SshClient(
+            cls.mgtSvrDetails["mgtSvrIp"],
+            22,
+            cls.mgtSvrDetails["user"],
+            cls.mgtSvrDetails["passwd"]
+        )
+
+        command = "service cloudstack-usage status"
+        response = str(sshClient.execute(command)).lower()
+        if "running" not in response:
+            return False
+        return True
+
+    def getLatestUsageJobExecutionTime(self):
+        """ Get the end time of latest usage job that has run successfully"""
+
+        try:
+            qresultset = self.dbclient.execute(
+                "SELECT max(end_date) FROM usage_job WHERE success=1;",
+                db="cloud_usage")
+
+            self.assertNotEqual(
+                len(qresultset),
+                0,
+                "Check DB Query result set"
+            )
+
+            lastUsageJobExecutionTime = qresultset[0][0]
+            self.debug(
+                "last usage job exec time: %s" %
+                lastUsageJobExecutionTime)
+            return [PASS, lastUsageJobExecutionTime]
+        except Exception as e:
+            return [FAIL, e]
+
+    def getEventCreatedDateTime(self, resourceName):
+        """ Get the created date/time of particular entity
+            from cloud_usage.usage_event table """
+
+        try:
+            # Checking exact entity creation time
+            qresultset = self.dbclient.execute(
+                "select created from usage_event where resource_name = '%s';" %
+                str(resourceName), db="cloud_usage")
+            self.assertNotEqual(
+                len(qresultset),
+                0,
+                "Check DB Query result set"
+            )
+            eventCreatedDateTime = qresultset[0][0]
+        except Exception as e:
+            return [FAIL, e]
+        return [PASS, eventCreatedDateTime]
+
+    def listUsageRecords(self, usagetype, apiclient=None, startdate=None,
+                         enddate=None, account=None, sleep=True):
+        """List and return the usage record for given account
+        and given usage type"""
+
+        if sleep:
+            # Sleep till usage job has run at least once after the operation
+            self.debug(
+                "Sleeping for %s seconds" %
+                self.usageJobAggregationRange)
+            time.sleep(self.usageJobAggregationRange)
+
+        if not startdate:
+            startdate = self.curDate
+        if not enddate:
+            enddate = self.curDate
+        if not account:
+            account = self.account
+        if not apiclient:
+            self.apiclient
+
+        Usage.generateRecords(
+            self.apiclient,
+            startdate=startdate,
+            enddate=enddate)
+
+        try:
+            usageRecords = Usage.listRecords(
+                self.apiclient,
+                startdate=startdate,
+                enddate=enddate,
+                account=account.name,
+                domainid=account.domainid,
+                type=usagetype)
+
+            self.assertEqual(
+                validateList(usageRecords)[0],
+                PASS,
+                "usage records list validation failed")
+
+            return [PASS, usageRecords]
+        except Exception as e:
+            return [FAIL, e]
+        return
+
+    def getCommandResultFromRouter(self, router, command):
+        """Run given command on router and return the result"""
+
+        if (self.hypervisor.lower() == 'vmware'
+                or self.hypervisor.lower() == 'hyperv'):
+            result = get_process_status(
+                self.apiclient.connection.mgtSvr,
+                22,
+                self.apiclient.connection.user,
+                self.apiclient.connection.passwd,
+                router.linklocalip,
+                command,
+                hypervisor=self.hypervisor
+            )
+        else:
+            hosts = list_hosts(
+                self.apiclient,
+                id=router.hostid,
+            )
+            self.assertEqual(
+                isinstance(hosts, list),
+                True,
+                "Check for list hosts response return valid data"
+            )
+            host = hosts[0]
+            host.user = self.testdata["configurableData"]["host"]["username"]
+            host.passwd = self.testdata["configurableData"]["host"]["password"]
+
+            result = get_process_status(
+                host.ipaddress,
+                22,
+                host.user,
+                host.passwd,
+                router.linklocalip,
+                command
+            )
+        return result
+
+    @attr(tags=["advanced"], required_hardware="true")
+    def test_01_positive_tests_usage(self):
+        """ Positive test for usage test path
+
+        # 1.  Register a template and verify that usage usage is generated
+              for correct size of template
+        # 2.  Register an ISO, verify usage is generate for the correct size
+              of ISO
+        # 3.  Deploy a VM from the template and verify usage is generated
+              for the VM with correct Service Offering and template id
+        # 4.  Delete template and iso
+        # 5.  Stop and start the VM
+        # 6.  Verify that allocated VM usage should be greater than
+              running VM usage
+        # 7.  Destroy the Vm and recover it
+        # 8.  Verify that the running VM usage stays the same after delete and
+              and after recover operation
+        # 9.  Verify that allocated VM usage should be greater after recover
+              operation than after destroy operation
+        # 10. Change service offering of the VM
+        # 11. Verify that VM usage is generated for the VM with correct
+              service offering
+        # 12. Start the VM
+        # 13. Verify that the running VM usage after start operation is less
+              than the allocated VM usage
+        # 14. Verify that the running VM usage after start vm opearation
+              is greater running VM usage after recover VM operation
+        """
+
+        # Step 1
+        # Register a private template in the account
+        builtin_info = get_builtin_template_info(
+            self.apiclient,
+            self.zone.id
+        )
+
+        self.testdata["privatetemplate"]["url"] = builtin_info[0]
+        self.testdata["privatetemplate"]["hypervisor"] = builtin_info[1]
+        self.testdata["privatetemplate"]["format"] = builtin_info[2]
+
+        # Register new template
+        template = Template.register(
+            self.userapiclient,
+            self.testdata["privatetemplate"],
+            zoneid=self.zone.id,
+            account=self.account.name,
+            domainid=self.account.domainid
+        )
+        self.cleanup.append(template)
+        template.download(self.userapiclient)
+
+        templates = Template.list(
+            self.userapiclient,
+            listall=True,
+            id=template.id,
+            templatefilter="self")
+
+        self.assertEqual(
+            validateList(templates)[0],
+            PASS,
+            "Templates list validation failed")
+
+        # Checking template usage
+        response = self.listUsageRecords(usagetype=7)
+        self.assertEqual(response[0], PASS, response[1])
+        templateUsageRecords = [record for record in response[1]
+                                if template.id == record.usageid]
+
+        self.assertEqual(templateUsageRecords[0].virtualsize,
+                         templates[0].size,
+                         "The template size in the usage record and \
+                        does not match with the created template size")
+
+        # Getting last usage job execution time
+        response = self.getLatestUsageJobExecutionTime()
+        self.assertEqual(response[0], PASS, response[1])
+        lastUsageJobExecTime = response[1]
+
+        # Checking exact template creation time
+        response = self.getEventCreatedDateTime(template.name)
+        self.assertEqual(response[0], PASS, response[1])
+        templateCreatedDateTime = response[1]
+        self.debug("Template creation date: %s" % templateCreatedDateTime)
+
+        # We have to get the expected usage count in hours as the rawusage returned by listUsageRecords
+        # is also in hours
+        expectedUsage = format(
+            ((lastUsageJobExecTime - templateCreatedDateTime).total_seconds() / 3600),
+            ".2f")
+
+        actualUsage = format(sum(float(record.rawusage)
+                                 for record in templateUsageRecords), ".2f")
+
+        self.assertEqual(
+            expectedUsage,
+            actualUsage,
+            "expected usage %s and actual usage %s not matching" %
+            (expectedUsage,
+             actualUsage))
+
+        # step 2
+        iso = Iso.create(
+            self.userapiclient,
+            self.testdata["iso"],
+            account=self.account.name,
+            domainid=self.account.domainid,
+            zoneid=self.zone.id
+        )
+        self.cleanup.append(iso)
+
+        iso.download(self.apiclient)
+
+        isos = Iso.list(
+            self.userapiclient,
+            id=iso.id,
+            listall=True)
+
+        self.assertEqual(
+            validateList(isos)[0],
+            PASS,
+            "Iso list validation failed"
+        )
+
+        # Checking usage for Iso
+        response = self.listUsageRecords(usagetype=8)
+        self.assertEqual(response[0], PASS, response[1])
+        isoUsageRecords = [record for record in response[1]
+                           if iso.id == record.usageid]
+
+        self.assertEqual(isoUsageRecords[0].size,
+                         isos[0].size,
+                         "The iso size in the usage record and \
+                        does not match with the created iso size")
+
+        # Getting last usage job execution time
+        response = self.getLatestUsageJobExecutionTime()
+        self.assertEqual(response[0], PASS, response[1])
+        lastUsageJobExecTime = response[1]
+
+        # Checking exact Iso creation time
+        response = self.getEventCreatedDateTime(iso.name)
+        self.assertEqual(response[0], PASS, response[1])
+        isoCreatedDateTime = response[1]
+        self.debug("Iso creation date: %s" % isoCreatedDateTime)
+
+        # We have to get the expected usage count in hours as the rawusage returned by listUsageRecords
+        # is also in hours
+        expectedUsage = format(
+            ((lastUsageJobExecTime - isoCreatedDateTime).total_seconds() / 3600),
+            ".2f")
+
+        actualUsage = format(sum(float(record.rawusage)
+                                 for record in isoUsageRecords), ".2f")
+
+        self.assertEqual(
+            expectedUsage,
+            actualUsage,
+            "expected usage %s and actual usage %s not matching" %
+            (expectedUsage,
+             actualUsage))
+
+        # step 3
+        # Create VM in account
+        vm = VirtualMachine.create(
+            self.userapiclient,
+            self.testdata["small"],
+            templateid=template.id,
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            serviceofferingid=self.service_offering.id,
+            zoneid=self.zone.id
+        )
+
+        # Checking running VM usage
+        response = self.listUsageRecords(usagetype=1)
+        self.assertEqual(response[0], PASS, response[1])
+        vmRunningUsageRecords = [record for record in response[1]
+                                 if record.virtualmachineid == vm.id]
+
+        vmRunningRawUsage = sum(float(record.rawusage)
+                                for record in vmRunningUsageRecords)
+
+        self.assertEqual(vmRunningUsageRecords[0].offeringid,
+                         self.service_offering.id,
+                         "The service offering id in the usage record\
+                        does not match with id of service offering\
+                        with which the VM was created")
+
+        self.assertEqual(vmRunningUsageRecords[0].templateid,
+                         template.id,
+                         "The template id in the usage record\
+                        does not match with id of template\
+                        with which the VM was created")
+
+        response = self.listUsageRecords(usagetype=2, sleep=False)
+        self.assertEqual(response[0], PASS, response[1])
+        vmAllocatedUsageRecords = [record for record in response[1]
+                                   if record.virtualmachineid == vm.id]
+
+        vmAllocatedRawUsage = sum(float(record.rawusage)
+                                  for record in vmAllocatedUsageRecords)
+
+        self.debug("running vm usage: %s" % vmRunningRawUsage)
+        self.debug("allocated vm usage: %s" % vmAllocatedRawUsage)
+
+        self.assertTrue(
+            vmRunningRawUsage < vmAllocatedRawUsage,
+            "Allocated VM usage should be greater than Running VM usage")
+
+        # Getting last usage job execution time
+        response = self.getLatestUsageJobExecutionTime()
+        self.assertEqual(response[0], PASS, response[1])
+        lastUsageJobExecTime = response[1]
+
+        # Checking exact VM creation time
+        response = self.getEventCreatedDateTime(vm.name)
+        self.assertEqual(response[0], PASS, response[1])
+        vmCreatedDateTime = response[1]
+        self.debug("Vm creation date: %s" % vmCreatedDateTime)
+
+        # We have to get the expected usage count in hours as the rawusage returned by listUsageRecords
+        # is also in hours
+        expectedUsage = format(
+            ((lastUsageJobExecTime - vmCreatedDateTime).total_seconds() / 3600),
+            ".2f")
+        self.debug("VM expected usage: %s" % expectedUsage)
+
+        actualUsage = format(vmAllocatedRawUsage, ".2f")
+
+        self.assertEqual(
+            expectedUsage,
+            actualUsage,
+            "expected usage %s and actual usage %s not matching" %
+            (expectedUsage,
+             actualUsage))
+
+        # Step 4 - Deleting template and ISO
+        template.delete(self.userapiclient)
+        self.cleanup.remove(template)
+
+        iso.delete(self.userapiclient)
+        self.cleanup.remove(iso)
+
+        # Verifying that usage for template and ISO is stopped
+        response = self.listUsageRecords(usagetype=7)
+        self.assertEqual(response[0], PASS, response[1])
+        templateUsageRecords = response[1]
+
+        usageForTemplateAfterDeletion_1 = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in templateUsageRecords
+                if template.id == record.usageid])
+
+        response = self.listUsageRecords(usagetype=8, sleep=False)
+        self.assertEqual(response[0], PASS, response[1])
+        isoUsageRecords = response[1]
+
+        usageForIsoAfterDeletion_1 = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in isoUsageRecords
+                if iso.id == record.usageid])
+
+        response = self.listUsageRecords(usagetype=7)
+        self.assertEqual(response[0], PASS, response[1])
+        templateUsageRecords = response[1]
+
+        usageForTemplateAfterDeletion_2 = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in templateUsageRecords
+                if template.id == record.usageid])
+
+        response = self.listUsageRecords(usagetype=8, sleep=False)
+        self.assertEqual(response[0], PASS, response[1])
+        isoUsageRecords = response[1]
+
+        usageForIsoAfterDeletion_2 = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in isoUsageRecords
+                if iso.id == record.usageid])
+
+        self.assertTrue(usageForTemplateAfterDeletion_1 ==
+                        usageForTemplateAfterDeletion_2,
+                        "usage for template after deletion should remain the same\
+                        after specific intervals of time")
+
+        self.assertTrue(usageForIsoAfterDeletion_1 ==
+                        usageForIsoAfterDeletion_2,
+                        "usage for iso after deletion should remain the same\
+                        after specific intervals of time")
+
+        # Step 5
+        vm.stop(self.userapiclient)
+
+        # Sleep to get difference between allocated and running usage
+        time.sleep(120)
+
+        vm.start(self.userapiclient)
+
+        # Step 6: Verifying allocated usage is greater than running usage
+        response = self.listUsageRecords(usagetype=1)
+        self.assertEqual(response[0], PASS, response[1])
+        vmRunningUsageRecords = [record for record in response[1]
+                                 if record.virtualmachineid == vm.id]
+
+        vmRunningRawUsage = sum(float(record.rawusage)
+                                for record in vmRunningUsageRecords)
+
+        response = self.listUsageRecords(usagetype=2, sleep=False)
+        self.assertEqual(response[0], PASS, response[1])
+        vmAllocatedUsageRecords = [record for record in response[1]
+                                   if record.virtualmachineid == vm.id]
+
+        vmAllocatedRawUsage = sum(float(record.rawusage)
+                                  for record in vmAllocatedUsageRecords)
+
+        self.debug("running vm usage: %s" % vmRunningRawUsage)
+        self.debug("allocated vm usage: %s" % vmAllocatedRawUsage)
+
+        self.assertTrue(
+            vmRunningRawUsage < vmAllocatedRawUsage,
+            "Allocated VM usage should be greater than Running VM usage")
+
+        # Step 7
+        vm.delete(self.userapiclient, expunge=False)
+
+        response = self.listUsageRecords(usagetype=1, sleep=False)
+        self.assertEqual(response[0], PASS, response[1])
+        vmRunningUsageRecordAfterDestroy = sum(
+            float(
+                record.rawusage) for record in response[1] if
+            record.virtualmachineid == vm.id)
+
+        response = self.listUsageRecords(usagetype=2, sleep=False)
+        self.assertEqual(response[0], PASS, response[1])
+        vmAllocatedUsageRecordAfterDestroy = sum(
+            float(
+                record.rawusage) for record in response[1] if record.virtualmachineid == vm.id)
+
+        vm.recover(self.apiclient)
+
+        # Step 8
+        response = self.listUsageRecords(usagetype=1)
+        self.assertEqual(response[0], PASS, response[1])
+        vmRunningUsageRecordAfterRecover = sum(
+            float(
+                record.rawusage) for record in response[1] if
+            record.virtualmachineid == vm.id)
+
+        response = self.listUsageRecords(usagetype=2, sleep=False)
+        self.assertEqual(response[0], PASS, response[1])
+        vmAllocatedUsageRecordAfterRecover = sum(
+            float(
+                record.rawusage) for record in response[1] if
+            record.virtualmachineid == vm.id)
+
+        self.debug(
+            "running vm usage T1: %s" %
+            vmRunningUsageRecordAfterDestroy)
+        self.debug(
+            "allocated vm usage T1: %s" %
+            vmRunningUsageRecordAfterRecover)
+
+        self.assertEqual(
+            format(vmRunningUsageRecordAfterDestroy, ".1f"),
+            format(vmRunningUsageRecordAfterRecover, ".1f"),
+            "Running usage should remain the same")
+
+        self.debug(
+            "allocated vm usage T2: %s" %
+            vmAllocatedUsageRecordAfterDestroy)
+        self.debug(
+            "allocated vm usage T2: %s" %
+            vmAllocatedUsageRecordAfterRecover)
+
+        # Step 9
+        self.assertTrue(
+            vmAllocatedUsageRecordAfterDestroy <
+            vmAllocatedUsageRecordAfterRecover,
+            "Allocated VM usage after recover should be greater than\
+                        before")
+
+        # Step 10
+        # Change service offering of VM and verify that it is changed
+        vm.change_service_offering(
+            self.userapiclient,
+            serviceOfferingId=self.service_offering_2.id
+        )
+
+        response = self.listUsageRecords(usagetype=2)
+        self.assertEqual(response[0], PASS, response[1])
+        vmAllocatedUsageRecord = response[1][-1]
+
+        # Step 11: Veriying vm usage for new service offering
+        self.assertEqual(vmAllocatedUsageRecord.offeringid,
+                         self.service_offering_2.id,
+                         "The service offering id in the usage record\
+                        does not match with id of new service offering")
+
+        # Step 12
+        vm.start(self.userapiclient)
+
+        response = self.listUsageRecords(usagetype=1)
+        self.assertEqual(response[0], PASS, response[1])
+        vmRunningUsageRecordAfterStart = sum(
+            float(
+                record.rawusage) for record in response[1] if
+            record.virtualmachineid == vm.id)
+
+        response = self.listUsageRecords(usagetype=2, sleep=False)
+        self.assertEqual(response[0], PASS, response[1])
+        vmAllocatedUsageRecordAfterStart = sum(
+            float(
+                record.rawusage) for record in response[1] if
+            record.virtualmachineid == vm.id)
+
+        self.debug("running vm usage T3: %s" % vmRunningUsageRecordAfterStart)
+        self.debug(
+            "allocated vm usage T3: %s" %
+            vmAllocatedUsageRecordAfterStart)
+
+        # Step 13
+        self.assertTrue(
+            vmRunningUsageRecordAfterStart <
+            vmAllocatedUsageRecordAfterStart,
+            "Allocated VM usage should be greater than Running usage")
+
+        # Step 14
+        self.assertTrue(
+            vmRunningUsageRecordAfterRecover <
+            vmRunningUsageRecordAfterStart,
+            "Running VM usage after start VM should be greater than\
+                        that after recover operation")
+        return
+
+    @attr(tags=["advanced"], required_hardware="true")
+    def test_02_positive_tests_usage(self):
+        """ Positive test for usage test path
+
+        # 1.  Scale up VM and check that usage is generated for
+              new cpu and ram value (Check in usage_vm_instance table)
+        # 2.  Scale down VM and check that usage is generated for
+              new cpu and ram value (Check in usage_vm_instance table)
+        # 3.  Attach disk to VM and check that volume usage is
+              generated for correct disk offering
+        # 4.  Detach volume from and verify that usage for volue remains
+              the same there afterwards
+        # 5.  Create snapshot of the root disk and verify correct usage is
+              generated for snapshot with correct size
+        # 6.  Create template from root disk and check correct usage is
+              generated for template with correct size
+        # 7.  Delete the template and verify that usage is stopped for
+              template
+        # 8.  Create volume from snaopshot and verify correct disk usage
+              is generated
+        # 9.  Delete the volume and verify that the usage is stopped
+        # 10. Create template from snapshot and verify correct usage
+              is generated for the template with correct size
+        """
+
+        # Step 1
+        # Create dynamic and static service offering
+        self.testdata["service_offering"]["cpunumber"] = ""
+        self.testdata["service_offering"]["cpuspeed"] = ""
+        self.testdata["service_offering"]["memory"] = ""
+
+        serviceOffering_dynamic = ServiceOffering.create(
+            self.apiclient,
+            self.testdata["service_offering"]
+        )
+        self.cleanup.append(serviceOffering_dynamic)
+
+        customcpunumber = 1
+        customcpuspeed = 256
+        custommemory = 128
+
+        # Deploy VM with dynamic service offering
+        virtualMachine = VirtualMachine.create(
+            self.userapiclient,
+            self.testdata["virtual_machine"],
+            serviceofferingid=serviceOffering_dynamic.id,
+            templateid=self.template.id,
+            zoneid=self.zone.id,
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            customcpunumber=customcpunumber,
+            customcpuspeed=customcpuspeed,
+            custommemory=custommemory
+        )
+
+        # Stop VM and verify that it is in stopped state
+        virtualMachine.stop(self.userapiclient)
+
+        scaledcpunumber = 2
+        scaledcpuspeed = 512
+        scaledmemory = 256
+
+        # Scale up VM
+        virtualMachine.scale(
+            self.userapiclient,
+            serviceOfferingId=serviceOffering_dynamic.id,
+            customcpunumber=scaledcpunumber,
+            customcpuspeed=scaledcpuspeed,
+            custommemory=scaledmemory
+        )
+
+        self.listUsageRecords(usagetype=1)
+
+        qresultset = self.dbclient.execute(
+            "select cpu_cores, memory, cpu_speed from usage_vm_instance where vm_name = '%s';" %
+            str(virtualMachine.name), db="cloud_usage")
+        self.assertNotEqual(
+            len(qresultset),
+            0,
+            "Check DB Query result set"
+        )
+        dbcpucores = qresultset[-1][0]
+        dbmemory = qresultset[-1][1]
+        dbcpuspeed = qresultset[-1][2]
+
+        self.assertEqual(int(dbcpucores), scaledcpunumber,
+                         "scaled cpu number not matching with db record")
+
+        self.assertEqual(int(dbmemory), scaledmemory,
+                         "scaled memory not matching with db record")
+
+        self.assertEqual(int(dbcpuspeed), scaledcpuspeed,
+                         "scaled cpu speed not matching with db record")
+
+        scaledcpunumber = 1
+        scaledcpuspeed = 512
+        scaledmemory = 256
+
+        # Step 2
+        # Scale down VM
+        virtualMachine.scale(
+            self.userapiclient,
+            serviceOfferingId=serviceOffering_dynamic.id,
+            customcpunumber=scaledcpunumber,
+            customcpuspeed=scaledcpuspeed,
+            custommemory=scaledmemory
+        )
+
+        self.listUsageRecords(usagetype=1)
+
+        qresultset = self.dbclient.execute(
+            "select cpu_cores, memory, cpu_speed from usage_vm_instance where vm_name = '%s';" %
+            str(virtualMachine.name), db="cloud_usage")
+        self.assertNotEqual(
+            len(qresultset),
+            0,
+            "Check DB Query result set"
+        )
+        dbcpucores = qresultset[-1][0]
+        dbmemory = qresultset[-1][1]
+        dbcpuspeed = qresultset[-1][2]
+
+        self.assertEqual(int(dbcpucores), scaledcpunumber,
+                         "scaled cpu number not matching with db record")
+
+        self.assertEqual(int(dbmemory), scaledmemory,
+                         "scaled memory not matching with db record")
+
+        self.assertEqual(int(dbcpuspeed), scaledcpuspeed,
+                         "scaled cpu speed not matching with db record")
+
+        disk_offering = DiskOffering.create(
+            self.apiclient,
+            self.testdata["disk_offering"]
+        )
+        self.cleanup.append(disk_offering)
+
+        # Step 3
+        volume = Volume.create(
+            self.userapiclient, self.testdata["volume"],
+            zoneid=self.zone.id, account=self.account.name,
+            domainid=self.account.domainid, diskofferingid=disk_offering.id
+        )
+
+        # Create VM in account
+        virtual_machine = VirtualMachine.create(
+            self.userapiclient,
+            self.testdata["small"],
+            templateid=self.template.id,
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            serviceofferingid=self.service_offering.id,
+            zoneid=self.zone.id
+        )
+
+        virtual_machine.attach_volume(self.userapiclient, volume=volume)
+
+        # Verifying usage for Volume - START
+        response = self.listUsageRecords(usagetype=6)
+        self.assertEqual(response[0], PASS, response[1])
+        volumeUsageRecords = [record for record in response[1]
+                              if volume.id == record.usageid]
+
+        self.assertTrue(
+            len(volumeUsageRecords) >= 1,
+            "Volume usage record for attached volume is not generated")
+
+        volumeRawUsageBeforeDetach = sum(float(record.rawusage) for
+                                         record in [
+            record for record in volumeUsageRecords
+            if volume.id == record.usageid])
+
+        # Getting last usage job execution time
+        response = self.getLatestUsageJobExecutionTime()
+        self.assertEqual(response[0], PASS, response[1])
+        lastUsageJobExecTime = response[1]
+
+        # Checking exact Volume creation time
+        response = self.getEventCreatedDateTime(volume.name)
+        self.assertEqual(response[0], PASS, response[1])
+        volumeCreatedDateTime = response[1]
+        self.debug("Volume creation date: %s" % volumeCreatedDateTime)
+
+        # We have to get the expected usage count in hours as the rawusage returned by listUsageRecords
+        # is also in hours
+        expectedUsage = format(
+            ((lastUsageJobExecTime - volumeCreatedDateTime).total_seconds() / 3600),
+            ".2f")
+        self.debug("Volume expected usage: %s" % expectedUsage)
+
+        actualUsage = format(volumeRawUsageBeforeDetach, ".2f")
+
+        self.assertEqual(
+            expectedUsage,
+            actualUsage,
+            "expected usage %s and actual usage %s not matching" %
+            (expectedUsage,
+             actualUsage))
+
+        # Verifying usage for Volume - END
+
+        # Step 4
+        virtual_machine.detach_volume(self.userapiclient, volume=volume)
+
+        # Verifying usage for Volume after detaching - START
+        response = self.listUsageRecords(usagetype=6)
+        self.assertEqual(response[0], PASS, response[1])
+        volumeUsageRecords = response[1]
+
+        volumeRawUsageAfterDetach_time_1 = sum(float(record.rawusage) for
+                                               record in [
+            record for record in volumeUsageRecords
+            if volume.id == record.usageid])
+
+        response = self.listUsageRecords(usagetype=6)
+        self.assertEqual(response[0], PASS, response[1])
+        volumeUsageRecords = response[1]
+
+        volumeRawUsageAfterDetach_time_2 = sum(float(record.rawusage) for
+                                               record in [
+            record for record in volumeUsageRecords
+            if volume.id == record.usageid])
+
+        self.debug(volumeRawUsageAfterDetach_time_1)
+        self.debug(volumeRawUsageAfterDetach_time_2)
+
+        self.assertTrue(
+            volumeRawUsageAfterDetach_time_1 <
+            volumeRawUsageAfterDetach_time_2,
+            "Raw volume usage should continue running after detach operation"
+        )
+
+        # Verifying usage for Volume after detaching - END
+
+        volumes = Volume.list(
+            self.userapiclient,
+            virtualmachineid=virtual_machine.id,
+            type='ROOT',
+            listall=True
+        )
+        self.assertEqual(
+            validateList(volumes)[0],
+            PASS,
+            "Volumes list validation failed"
+        )
+
+        rootVolume = volumes[0]
+
+        # Step 5
+        # Create a snapshot from the ROOTDISK
+        snapshotFromRootVolume = Snapshot.create(
+            self.userapiclient,
+            rootVolume.id)
+
+
+        # Verifying usage for Snapshot - START
+        response = self.listUsageRecords(usagetype=9)
+        self.assertEqual(response[0], PASS, response[1])
+        snapshotUsageRecords = [record for record in response[1]
+                                if snapshotFromRootVolume.id == record.usageid]
+
+        self.assertEqual(snapshotUsageRecords[0].size,
+                         snapshotFromRootVolume.physicalsize,
+                         "The snapshot size in the usage record and \
+                        does not match with the created snapshot size")
+
+        # Getting last usage job execution time
+        response = self.getLatestUsageJobExecutionTime()
+        self.assertEqual(response[0], PASS, response[1])
+        lastUsageJobExecTime = response[1]
+
+        # Checking exact snapshot creation time
+        response = self.getEventCreatedDateTime(snapshotFromRootVolume.name)
+        self.assertEqual(response[0], PASS, response[1])
+        snapshotCreatedDateTime = response[1]
+        self.debug("Snapshot creation date: %s" % snapshotCreatedDateTime)
+
+        # We have to get the expected usage count in hours as the rawusage returned by listUsageRecords
+        # is also in hours
+        expectedUsage = format(
+            ((lastUsageJobExecTime - snapshotCreatedDateTime).total_seconds() / 3600),
+            ".2f")
+
+        actualUsage = format(sum(float(record.rawusage)
+                                 for record in snapshotUsageRecords), ".2f")
+
+        self.assertEqual(
+            expectedUsage,
+            actualUsage,
+            "expected usage %s and actual usage %s not matching" %
+            (expectedUsage,
+             actualUsage))
+
+        # Verifying usage for Snapshot - END
+
+        virtual_machine.stop(self.userapiclient)
+
+        # Step 6
+        templateFromVolume = Template.create(
+            self.userapiclient,
+            self.testdata["templates"],
+            rootVolume.id,
+            self.account.name,
+            self.account.domainid
+        )
+
+        templates = Template.list(
+            self.userapiclient,
+            listall=True,
+            id=templateFromVolume.id,
+            templatefilter="self"
+        )
+
+        self.assertEqual(
+            validateList(templates)[0],
+            PASS,
+            "templates list validation failed"
+        )
+
+        # Verifying usage for Template - START
+        response = self.listUsageRecords(usagetype=7)
+        self.assertEqual(response[0], PASS, response[1])
+        templateUsageRecords = [record for record in response[1]
+                                if templateFromVolume.id == record.usageid]
+
+        self.assertEqual(templateUsageRecords[0].virtualsize,
+                         templates[-1].size,
+                         "The template size in the usage record and \
+                        does not match with the created template size")
+
+        templateRawUsage = sum(float(record.rawusage)
+                               for record in templateUsageRecords)
+
+        # Getting last usage job execution time
+        response = self.getLatestUsageJobExecutionTime()
+        self.assertEqual(response[0], PASS, response[1])
+        lastUsageJobExecTime = response[1]
+
+        # Checking exact Template creation time
+        response = self.getEventCreatedDateTime(templateFromVolume.name)
+        self.assertEqual(response[0], PASS, response[1])
+        templateCreatedDateTime = response[1]
+        self.debug("Template creation date: %s" % templateCreatedDateTime)
+
+        # We have to get the expected usage count in hours as the rawusage returned by listUsageRecords
+        # is also in hours
+        expectedUsage = format(
+            ((lastUsageJobExecTime - templateCreatedDateTime).total_seconds() / 3600),
+            ".2f")
+        self.debug("Template expected usage: %s" % expectedUsage)
+
+        actualUsage = format(templateRawUsage, ".2f")
+
+        self.assertEqual(
+            expectedUsage,
+            actualUsage,
+            "expected usage %s and actual usage %s not matching" %
+            (expectedUsage,
+             actualUsage))
+
+        # Verifying usage for Template - END
+
+        # Step 7
+        templateFromVolume.delete(self.userapiclient)
+
+
+        # Verifying usage for Template is stoppd after deleting it - START
+        response = self.listUsageRecords(usagetype=7)
+        self.assertEqual(response[0], PASS, response[1])
+        templateUsageRecords = response[1]
+
+        usageForTemplateFromVolumeAfterDeletion_1 = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in templateUsageRecords
+                if templateFromVolume.id == record.usageid])
+
+        response = self.listUsageRecords(usagetype=7)
+        self.assertEqual(response[0], PASS, response[1])
+        templateUsageRecords = response[1]
+
+        usageForTemplateFromVolumeAfterDeletion_2 = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in templateUsageRecords
+                if templateFromVolume.id == record.usageid])
+
+        self.assertTrue(usageForTemplateFromVolumeAfterDeletion_1 ==
+                        usageForTemplateFromVolumeAfterDeletion_2,
+                        "usage for template after deletion should remain the same\
+                        after specific intervals of time")
+
+        # Verifying usage for Template is stoppd after deleting it - END
+
+        # Step 8
+        self.testdata["volume_from_snapshot"]["zoneid"] = self.zone.id
+
+        volumeFromSnapshot = Volume.create_from_snapshot(
+            self.userapiclient,
+            snapshot_id=snapshotFromRootVolume.id,
+            services=self.testdata["volume_from_snapshot"],
+            account=self.account.name,
+            domainid=self.account.domainid
+        )
+
+        # Verifying usage for Volume from Snapshot - START
+        response = self.listUsageRecords(usagetype=6)
+        self.assertEqual(response[0], PASS, response[1])
+        volumeUsageRecords = response[1]
+
+        usageForVolumeFromSnapshotBeforeDeletion = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in volumeUsageRecords
+                if volumeFromSnapshot.id == record.usageid])
+
+        self.debug(usageForVolumeFromSnapshotBeforeDeletion)
+
+        # Getting last usage job execution time
+        response = self.getLatestUsageJobExecutionTime()
+        self.assertEqual(response[0], PASS, response[1])
+        lastUsageJobExecTime = response[1]
+
+        # Checking exact Volume creation time
+        response = self.getEventCreatedDateTime(volumeFromSnapshot.name)
+        self.assertEqual(response[0], PASS, response[1])
+        volumeCreatedDateTime = response[1]
+        self.debug("Volume creation date: %s" % volumeCreatedDateTime)
+
+        # We have to get the expected usage count in hours as the rawusage returned by listUsageRecords
+        # is also in hours
+        expectedUsage = format(
+            ((lastUsageJobExecTime - volumeCreatedDateTime).total_seconds() / 3600),
+            ".2f")
+        self.debug("Volume expected usage: %s" % expectedUsage)
+
+        actualUsage = format(usageForVolumeFromSnapshotBeforeDeletion, ".2f")
+
+        self.assertEqual(
+            expectedUsage,
+            actualUsage,
+            "expected usage %s and actual usage %s not matching" %
+            (expectedUsage,
+             actualUsage))
+
+        # Verifying usage for Volume from Snapshot - END
+
+        # Step 9
+        volumeFromSnapshot.delete(self.userapiclient)
+
+
+        # Verifying usage for Volume from Snapshot is stopped after delete - START
+        response = self.listUsageRecords(usagetype=6)
+        self.assertEqual(response[0], PASS, response[1])
+        volumeUsageRecords = response[1]
+
+        usageForVolumeFromSnapshotAfterDeletion_1 = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in volumeUsageRecords
+                if volumeFromSnapshot.id == record.usageid])
+
+        response = self.listUsageRecords(usagetype=6)
+        self.assertEqual(response[0], PASS, response[1])
+        volumeUsageRecords = response[1]
+
+        usageForVolumeFromSnapshotAfterDeletion_2 = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in volumeUsageRecords
+                if volumeFromSnapshot.id == record.usageid])
+
+        self.debug(usageForVolumeFromSnapshotAfterDeletion_1)
+        self.debug(usageForVolumeFromSnapshotAfterDeletion_2)
+
+        self.assertTrue(usageForVolumeFromSnapshotAfterDeletion_1 ==
+                        usageForVolumeFromSnapshotAfterDeletion_2,
+                        "usage for volume after deletion should remain the same\
+                        after specific intervals of time")
+
+        # Verifying usage for Volume from Snapshot is stopped after delete - END
+
+        # Step 10
+        templateFromSnapshot = Template.create_from_snapshot(
+            self.userapiclient,
+            snapshotFromRootVolume,
+            self.testdata["privatetemplate"]
+        )
+
+        templates = Template.list(
+            self.userapiclient,
+            listall=True,
+            id=templateFromSnapshot.id,
+            templatefilter="self"
+        )
+
+        self.assertEqual(
+            validateList(templates)[0],
+            PASS,
+            "templates list validation failed"
+        )
+
+        # Verifying usage for Template from Snapshot - START
+        response = self.listUsageRecords(usagetype=7)
+        self.assertEqual(response[0], PASS, response[1])
+        usageRecords = response[1]
+
+        templateUsageRecords = [record for record in usageRecords
+                                if templateFromSnapshot.id == record.usageid]
+
+        self.assertTrue(len(templateUsageRecords) >= 1,
+                        "template usage record list is empty")
+
+        self.assertEqual(templateUsageRecords[-1].virtualsize,
+                         templates[0].size,
+                         "The template size in the usage record and \
+                        does not match with the created template size")
+
+        templateRawUsage = sum(float(record.rawusage)
+                               for record in templateUsageRecords)
+
+        # Getting last usage job execution time
+        response = self.getLatestUsageJobExecutionTime()
+        self.assertEqual(response[0], PASS, response[1])
+        lastUsageJobExecTime = response[1]
+
+        # Checking exact Template creation time
+        response = self.getEventCreatedDateTime(templateFromSnapshot.name)
+        self.assertEqual(response[0], PASS, response[1])
+        templateCreatedDateTime = response[1]
+        self.debug("Template creation date: %s" % templateCreatedDateTime)
+
+        # We have to get the expected usage count in hours as the rawusage returned by listUsageRecords
+        # is also in hours
+        expectedUsage = format(
+            ((lastUsageJobExecTime - templateCreatedDateTime).total_seconds() / 3600),
+            ".2f")
+        self.debug("Template expected usage: %s" % expectedUsage)
+
+        actualUsage = format(templateRawUsage, ".2f")
+
+        self.assertEqual(
+            expectedUsage,
+            actualUsage,
+            "expected usage %s and actual usage %s not matching" %
+            (expectedUsage,
+             actualUsage))
+
+        # Verifying usage for Template from Snapshot - END
+
+        templateFromSnapshot.delete(self.userapiclient)
+
+        # Verifying usage for Template from Snapshot is stopped after delete - START
+        response = self.listUsageRecords(usagetype=7)
+        self.assertEqual(response[0], PASS, response[1])
+        templateUsageRecords = response[1]
+
+        usageForTemplateAfterDeletion_1 = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in templateUsageRecords
+                if templateFromSnapshot.id == record.usageid])
+
+        response = self.listUsageRecords(usagetype=7)
+        self.assertEqual(response[0], PASS, response[1])
+        templateUsageRecords = response[1]
+
+        usageForTemplateAfterDeletion_2 = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in templateUsageRecords
+                if templateFromSnapshot.id == record.usageid])
+
+        self.assertTrue(usageForTemplateAfterDeletion_1 ==
+                        usageForTemplateAfterDeletion_2,
+                        "usage for volume after deletion should remain the same\
+                        after specific intervals of time")
+
+        # Verifying usage for Template from Snapshot is stopped after delete - END
+
+        snapshotFromRootVolume.delete(self.userapiclient)
+
+        # Verifying usage for Snapshot from volume is stopped after delete - START
+        response = self.listUsageRecords(usagetype=9)
+        self.assertEqual(response[0], PASS, response[1])
+        templateUsageRecords = response[1]
+
+        usageForSnapshotAfterDeletion_1 = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in templateUsageRecords
+                if snapshotFromRootVolume.id == record.usageid])
+
+        response = self.listUsageRecords(usagetype=9)
+        self.assertEqual(response[0], PASS, response[1])
+        templateUsageRecords = response[1]
+
+        usageForSnapshotAfterDeletion_2 = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in templateUsageRecords
+                if snapshotFromRootVolume.id == record.usageid])
+
+        self.assertTrue(usageForSnapshotAfterDeletion_1 ==
+                        usageForSnapshotAfterDeletion_2,
+                        "usage for volume after deletion should remain the same\
+                        after specific intervals of time")
+
+        # Verifying usage for Snapshot from volume is stopped after delete - END
+        return
+
+    @attr(tags=["advanced"], required_hardware="true")
+    def test_03_positive_tests_usage(self):
+        """ Positive test for usage test path T28 - T35
+
+        Steps:
+        # 1. Add an isolated network to VM and verify that network offering
+             usage is generated for account
+             Also verify that IP usage is generated for source NAT IP of
+             network
+        # 2. Enabled VPN on source nat IP of default network of VM
+        # 3. Add two VPN users and check that usage is generated for VPN users
+        # 4. Acquire public IP in the network and verify that IP usage
+             is generated for the acquired IP
+        # 5. Create two PF rules on this IP and verify that PF rules usage
+             is generated for the account
+        # 6. Acquire another IP and enabled static NAT on it and create
+             egress firewall rule on it
+        # 7. Verify IP usage is generated for above acquired IP
+        # 8. SSH to VM with above IP and ping to google.com
+        # 9. Verify that Network bytes usage is generated for account
+             and it matches with the actual number of bytes
+        # 10. Repeat the same for other acquired IP
+        # 11. Delete one of the PF rules and verify that usage is stopped for the PF rule
+        # 12. Also verify that usage is not stopped for other PF rule which
+        #     is still present
+        """
+
+        # Step 1
+        # Create VM in account
+        virtual_machine = VirtualMachine.create(
+            self.userapiclient,
+            self.testdata["small"],
+            templateid=self.template.id,
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            serviceofferingid=self.service_offering.id,
+            zoneid=self.zone.id
+        )
+
+        self.testdata["isolated_network"]["zoneid"] = self.zone.id
+        isolated_network = Network.create(
+            self.userapiclient,
+            self.testdata["isolated_network"],
+            self.account.name,
+            self.account.domainid,
+            networkofferingid=self.isolated_network_offering_2.id)
+
+        virtual_machine.add_nic(self.userapiclient, isolated_network.id)
+
+        # Usages for steps are checked together in batch after the operations are done
+        # to avoid waiting for usage job to run for each operation separately
+
+        # Listing source nat ip of newly added network
+        ipAddresses = PublicIPAddress.list(
+            self.apiclient,
+            associatednetworkid=isolated_network.id,
+            listall=True)
+
+        sourceNatIP = ipAddresses[0]
+
+        ipAddressesDefaultNetwork = PublicIPAddress.list(
+            self.apiclient,
+            associatednetworkid=virtual_machine.nic[0].networkid,
+            listall=True)
+
+        sourceNatIPDefaultNetwork = ipAddressesDefaultNetwork[0]
+
+        # Step 2
+        # Create VPN for source NAT ip
+        Vpn.create(self.apiclient,
+                   sourceNatIPDefaultNetwork.id,
+                   account=self.account.name,
+                   domainid=self.account.domainid)
+
+        self.debug("Verifying the remote VPN access")
+        vpns = Vpn.list(self.apiclient,
+                        publicipid=sourceNatIPDefaultNetwork.id,
+                        listall=True)
+        self.assertEqual(
+            isinstance(vpns, list),
+            True,
+            "List VPNs shall return a valid response"
+        )
+
+        # Step 3:
+        vpnuser_1 = VpnUser.create(
+            self.apiclient,
+            self.testdata["vpn_user"]["username"],
+            self.testdata["vpn_user"]["password"],
+            account=self.account.name,
+            domainid=self.account.domainid,
+            rand_name=True
+        )
+
+        vpnuser_2 = VpnUser.create(
+            self.apiclient,
+            self.testdata["vpn_user"]["username"],
+            self.testdata["vpn_user"]["password"],
+            account=self.account.name,
+            domainid=self.account.domainid,
+            rand_name=True
+        )
+
+        # Step 4
+        public_ip_1 = PublicIPAddress.create(
+            self.userapiclient,
+            accountid=virtual_machine.account,
+            zoneid=virtual_machine.zoneid,
+            domainid=virtual_machine.domainid,
+            services=self.testdata["server"],
+            networkid=virtual_machine.nic[0].networkid
+        )
+
+        FireWallRule.create(
+            self.userapiclient,
+            ipaddressid=public_ip_1.ipaddress.id,
+            protocol=self.testdata["fwrule"]["protocol"],
+            cidrlist=[self.testdata["fwrule"]["cidr"]],
+            startport=self.testdata["fwrule"]["startport"],
+            endport=self.testdata["fwrule"]["endport"]
+        )
+
+        # Step 5
+        self.testdata["natrule"]["startport"] = 22
+        self.testdata["natrule"]["endport"] = 22
+
+        nat_rule_1 = NATRule.create(
+            self.userapiclient,
+            virtual_machine,
+            self.testdata["natrule"],
+            public_ip_1.ipaddress.id
+        )
+
+        self.testdata["natrule"]["privateport"] = 23
+        self.testdata["natrule"]["publicport"] = 23
+
+        nat_rule_2 = NATRule.create(
+            self.userapiclient,
+            virtual_machine,
+            self.testdata["natrule"],
+            public_ip_1.ipaddress.id
+        )
+
+        # Usages for above operations are checked here together
+
+        # Checking usage for source nat IP of added network
+        response = self.listUsageRecords(usagetype=13)
+        self.assertEqual(response[0], PASS, response[1])
+        usageRecords = response[1]
+
+        nwOfferingUsageRecords = [
+            record for record in usageRecords if self.isolated_network_offering_2.id == record.offeringid]
+
+        self.assertTrue(validateList(nwOfferingUsageRecords)[0] == PASS,
+                        "IP usage record list validation failed")
+
+        self.assertTrue(float(nwOfferingUsageRecords[0].rawusage) > 0,
+                        "Raw usage not started for source NAT ip")
+
+        # Checking usage for source nat IP of default VM network
+        response = self.listUsageRecords(usagetype=3, sleep=False)
+        self.assertEqual(response[0], PASS, response[1])
+        usageRecords = response[1]
+
+        ipUsageRecords = [record for record in usageRecords
+                          if sourceNatIP.id == record.usageid]
+
+        self.assertTrue(validateList(ipUsageRecords)[0] == PASS,
+                        "IP usage record list validation failed")
+
+        self.assertTrue(float(ipUsageRecords[0].rawusage) > 0,
+                        "Raw usage not started for source NAT ip")
+
+        # Checking usage for acquired public IP
+        response = self.listUsageRecords(usagetype=3, sleep=False)
+        self.assertEqual(response[0], PASS, response[1])
+        usageRecords = response[1]
+
+        ipUsageRecords = [record for record
+                          in usageRecords
+                          if public_ip_1.ipaddress.id == record.usageid
+                          ]
+
+        self.assertTrue(validateList(ipUsageRecords)[0] == PASS,
+                        "IP usage record list validation failed")
+
+        self.assertTrue(float(ipUsageRecords[0].rawusage) > 0,
+                        "Raw usage not started for acquired public ip")
+
+        # Checking usage for NAT rules
+        response = self.listUsageRecords(usagetype=12, sleep=False)
+        self.assertEqual(response[0], PASS, response[1])
+        usageRecords = response[1]
+
+        natRuleUsageRecords = [record for record in usageRecords
+                               if nat_rule_1.id == record.usageid]
+
+        self.assertTrue(validateList(natRuleUsageRecords)[0] == PASS,
+                        "NAT rule usage record list validation failed")
+
+        self.assertTrue(float(natRuleUsageRecords[0].rawusage) > 0,
+                        "Raw usage not started for nat rule")
+
+        natRuleUsageRecords = [record for record in usageRecords
+                               if nat_rule_2.id == record.usageid]
+
+        self.assertTrue(validateList(natRuleUsageRecords)[0] == PASS,
+                        "NAT rule usage record list validation failed")
+
+        self.assertTrue(float(natRuleUsageRecords[0].rawusage) > 0,
+                        "Raw usage not started for nat rule")
+
+        # Checking VPN usage
+        response = self.listUsageRecords(usagetype=14, sleep=False)
+        self.assertEqual(response[0], PASS, response[1])
+        usageRecords = response[1]
+
+        vpnUserUsageRecords_1 = [record for record in usageRecords
+                                 if vpnuser_1.id == record.usageid]
+
+        self.assertTrue(validateList(vpnUserUsageRecords_1)[0] == PASS,
+                        "VPN user usage record list validation failed")
+
+        vpnuser1_rawusage = sum(float(record.rawusage)
+                                for record in vpnUserUsageRecords_1)
+
+        # Getting last usage job execution time
+        response = self.getLatestUsageJobExecutionTime()
+        self.assertEqual(response[0], PASS, response[1])
+        lastUsageJobExecTime = response[1]
+
+        # Checking exact VPN user creation time
+        response = self.getEventCreatedDateTime(vpnuser_1.username)
+        self.assertEqual(response[0], PASS, response[1])
+        vpnUserCreatedDateTime = response[1]
+        self.debug("VPN creation date: %s" % vpnUserCreatedDateTime)
+
+        # We have to get the expected usage count in hours as the rawusage returned by listUsageRecords
+        # is also in hours
+        expectedUsage = format(
+            ((lastUsageJobExecTime - vpnUserCreatedDateTime).total_seconds() / 3600),
+            ".2f")
+        self.debug("VPN user expected usage: %s" % expectedUsage)
+
+        actualUsage = format(vpnuser1_rawusage, ".2f")
+
+        self.assertEqual(
+            expectedUsage,
+            actualUsage,
+            "expected usage %s and actual usage %s not matching" %
+            (expectedUsage,
+             actualUsage))
+
+        vpnUserUsageRecords_2 = [record for record in usageRecords
+                                 if vpnuser_2.id == record.usageid]
+
+        self.assertTrue(validateList(vpnUserUsageRecords_2)[0] == PASS,
+                        "VPN user usage record list validation failed")
+
+        vpnuser2_rawusage = sum(float(record.rawusage)
+                                for record in vpnUserUsageRecords_2)
+
+        # Checking exact VPN user creation time
+        response = self.getEventCreatedDateTime(vpnuser_2.username)
+        self.assertEqual(response[0], PASS, response[1])
+        vpnUserCreatedDateTime = response[1]
+        self.debug("VPN creation date: %s" % vpnUserCreatedDateTime)
+
+        # We have to get the expected usage count in hours as the rawusage returned by listUsageRecords
+        # is also in hours
+        expectedUsage = format(
+            ((lastUsageJobExecTime - vpnUserCreatedDateTime).total_seconds() / 3600),
+            ".2f")
+        self.debug("VPN user expected usage: %s" % expectedUsage)
+
+        actualUsage = format(vpnuser2_rawusage, ".2f")
+
+        self.assertEqual(
+            expectedUsage,
+            actualUsage,
+            "expected usage %s and actual usage %s not matching" %
+            (expectedUsage,
+             actualUsage))
+
+        # Acquire another public IP and check usage
+        public_ip_2 = PublicIPAddress.create(
+            self.userapiclient,
+            accountid=virtual_machine.account,
+            zoneid=virtual_machine.zoneid,
+            domainid=virtual_machine.domainid,
+            services=self.testdata["server"],
+            networkid=virtual_machine.nic[0].networkid
+        )
+
+        # Step 6
+        # Enabling static Nat for Ip Address associated
+        StaticNATRule.enable(
+            self.userapiclient,
+            ipaddressid=public_ip_2.ipaddress.id,
+            virtualmachineid=virtual_machine.id,
+        )
+
+        # Step 7
+        response = self.listUsageRecords(usagetype=3)
+        self.assertEqual(response[0], PASS, response[1])
+        usageRecords = response[1]
+
+        ipUsageRecords = [record for record
+                          in usageRecords
+                          if public_ip_2.ipaddress.id == record.usageid
+                          ]
+
+        self.assertTrue(validateList(ipUsageRecords)[0] == PASS,
+                        "IP usage record list validation failed")
+
+        self.assertTrue(float(ipUsageRecords[0].rawusage) > 0,
+                        "Raw usage not started for public ip")
+
+        FireWallRule.create(
+            self.userapiclient,
+            ipaddressid=public_ip_2.ipaddress.id,
+            protocol=self.testdata["fwrule"]["protocol"],
+            cidrlist=[self.testdata["fwrule"]["cidr"]],
+            startport=self.testdata["fwrule"]["startport"],
+            endport=self.testdata["fwrule"]["endport"]
+        )
+
+        EgressFireWallRule.create(
+            self.userapiclient,
+            networkid=virtual_machine.nic[0].networkid,
+            protocol=self.testdata["icmprule"]["protocol"],
+            type=self.testdata["icmprule"]["icmptype"],
+            code=self.testdata["icmprule"]["icmpcode"],
+            cidrlist=self.testdata["icmprule"]["cidrlist"])
+
+        # Step 8:
+        ssh_client = virtual_machine.get_ssh_client(
+            ipaddress=public_ip_1.ipaddress.ipaddress
+        )
+
+        # Ping Internet and check the bytes received
+        res = ssh_client.execute("ping -c 1 www.google.com")
+        self.assertEqual(
+            str(res).count("1 received"),
+            1,
+            "Ping to outside world from VM should be successful"
+        )
+
+        routers = list_routers(
+            self.apiclient,
+            networkid=virtual_machine.nic[0].networkid,
+            listall=True
+        )
+        self.assertEqual(
+            validateList(routers)[0],
+            PASS,
+            "Routers list validation failed")
+        router = routers[0]
+
+        result = self.getCommandResultFromRouter(
+            router,
+            "iptables -L NETWORK_STATS -n -v -x")
+
+        self.debug("iptables -L NETWORK_STATS -n -v -x: %s" % result)
+
+        bytesReceivedIptableRows = [record for record in result if
+                                    "eth2   eth0" in record]
+        self.debug("bytes received rows: %s" % bytesReceivedIptableRows)
+        bytesReceivedOnRouter = sum(
+            int(record[1]) for record in [x.split() for x in bytesReceivedIptableRows])
+
+        self.debug(
+            "Bytes received extracted from router: %s" %
+            bytesReceivedOnRouter)
+
+        # Step 9:
+        # Verify that bytes received in usage are equal to
+        # as shown on router
+        response = self.listUsageRecords(usagetype=5)
+        self.assertEqual(response[0], PASS, response[1])
+        bytesReceivedUsage = sum(
+            int(record.rawusage) for record in response[1])
+
+        self.assertTrue(bytesReceivedUsage ==
+                        bytesReceivedOnRouter,
+                        "Total bytes received usage should be \
+                        equal to bytes received on router")
+
+        # Step 10:
+        # Repeat the same for other public IP
+        ssh_client = virtual_machine.get_ssh_client(
+            ipaddress=public_ip_2.ipaddress.ipaddress
+        )
+
+        res = ssh_client.execute("ping -c 1 www.google.com")
+        self.assertEqual(
+            str(res).count("1 received"),
+            1,
+            "Ping to outside world from VM should be successful"
+        )
+        result = self.getCommandResultFromRouter(
+            router,
+            "iptables -L NETWORK_STATS -n -v -x")
+
+        self.debug("iptables -L NETWORK_STATS -n -v -x: %s" % result)
+
+        bytesReceivedIptableRows = [record for record in result if
+                                    "eth2   eth0" in record]
+        self.debug("bytes received rows: %s" % bytesReceivedIptableRows)
+        bytesReceivedOnRouter = sum(
+            int(record[1]) for record in [x.split() for x in bytesReceivedIptableRows])
+
+        self.debug(
+            "Bytes received extracted from router: %s" %
+            bytesReceivedOnRouter)
+
+        # Step 9:
+        # Verify that bytes received in usage are equal to
+        # as shown on router
+        response = self.listUsageRecords(usagetype=5)
+        self.assertEqual(response[0], PASS, response[1])
+        bytesReceivedUsage = sum(
+            int(record.rawusage) for record in response[1])
+
+        self.assertTrue(bytesReceivedUsage ==
+                        bytesReceivedOnRouter,
+                        "Total bytes received usage should be \
+                        equal to bytes received on router")
+
+        # Step 11:
+        # Delete NAT rule and verify that usage is stopped for the NAT rule
+        nat_rule_1.delete(self.userapiclient)
+
+        response = self.listUsageRecords(usagetype=12, sleep=True)
+        self.assertEqual(response[0], PASS, response[1])
+        usageRecords = response[1]
+
+        natRule_1_Usage_t1 = sum(float(record.rawusage) for record
+                                 in [record for record in usageRecords
+                                     if nat_rule_1.id == record.usageid])
+
+        response = self.listUsageRecords(usagetype=12)
+        self.assertEqual(response[0], PASS, response[1])
+        usageRecords = response[1]
+
+        natRule_1_Usage_t2 = sum(float(record.rawusage) for record
+                                 in [record for record in usageRecords
+                                     if nat_rule_1.id == record.usageid])
+
+        self.assertTrue(
+            natRule_1_Usage_t1 == natRule_1_Usage_t2,
+            "NAT rule usage should be stopped once the rule is deleted")
+
+        # Also verify that usage for other nat rule is running
+        natRule_2_Usage_t1 = sum(float(record.rawusage) for record
+                                 in [record for record in usageRecords
+                                     if nat_rule_2.id == record.usageid])
+
+        # Step 12:
+        response = self.listUsageRecords(usagetype=12)
+        self.assertEqual(response[0], PASS, response[1])
+        usageRecords = response[1]
+
+        natRule_2_Usage_t2 = sum(float(record.rawusage) for record
+                                 in [record for record in usageRecords
+                                     if nat_rule_1.id == record.usageid])
+
+        self.assertTrue(natRule_2_Usage_t1 > natRule_2_Usage_t2,
+                        "NAT rule usage for second rule should be running")
+        return
+
+    @attr(tags=["advanced"], required_hardware="true")
+    def test_04_positive_tests_usage(self):
+        """ Positive test for usage test path
+        Steps:
+        # 1. Create a VM in the account
+        # 2. Acquire public IP in VM network and verify correct usage
+             is generated for IP
+        # 3. Create LB rule for the IP address and verify LB rule usage
+             is generated for the account
+        # 4. Create another LB rule with different ports and verify
+             seperate usage is generated for new LB rule
+
+        # 5. Create egress firewall rule for VM and SSH to VM
+        # 6. Ping external network from the VM and verify that
+             network byte usage is genrated correctly
+        # 7. Delete one LB rule and verify that the usage
+             is stopped for the LB rule
+        # 8. Stop the network router and
+        #    Verify iptables counters are reset when domR stops
+        #    Verify current_bytes in user_statistics table are moved to
+             net_bytes
+        #    Verify currnt_bytes becomes zero
+        # 9. Start the router and
+        #    Verify iptables counters are reset when domR starts
+        #    Verify a diff of total (current_bytes + net_bytes) in previous
+             aggregation period and current period will give the network usage
+
+        """
+
+        # Step 1
+        # Create VM in account
+        virtual_machine = VirtualMachine.create(
+            self.userapiclient,
+            self.testdata["small"],
+            templateid=self.template.id,
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            serviceofferingid=self.service_offering.id,
+            zoneid=self.zone.id
+        )
+
+        # Step 2
+        public_ip_1 = PublicIPAddress.create(
+            self.userapiclient,
+            accountid=virtual_machine.account,
+            zoneid=virtual_machine.zoneid,
+            domainid=virtual_machine.domainid,
+            services=self.testdata["server"]
+        )
+
+        self.testdata["lbrule"]["privateport"] = 22
+        self.testdata["lbrule"]["publicport"] = 2222
+        publicport = self.testdata["lbrule"]["publicport"]
+
+        # Step 3
+        # Create LB Rule
+        lbrule_1 = LoadBalancerRule.create(
+            self.apiclient,
+            self.testdata["lbrule"],
+            ipaddressid=public_ip_1.ipaddress.id,
+            accountid=self.account.name,
+            networkid=virtual_machine.nic[0].networkid,
+            domainid=self.account.domainid)
+
+        self.testdata["lbrule"]["privateport"] = 23
+        self.testdata["lbrule"]["publicport"] = 2223
+
+        # Step 4
+        # Create another LB Rule
+        lbrule_2 = LoadBalancerRule.create(
+            self.apiclient,
+            self.testdata["lbrule"],
+            ipaddressid=public_ip_1.ipaddress.id,
+            accountid=self.account.name,
+            networkid=virtual_machine.nic[0].networkid,
+            domainid=self.account.domainid)
+
+        response = self.listUsageRecords(usagetype=3)
+        self.assertEqual(response[0], PASS, response[1])
+        usageRecords = response[1]
+
+        ipUsageRecords = [record for record in usageRecords
+                          if public_ip_1.ipaddress.id == record.usageid
+                          ]
+
+        self.assertTrue(validateList(ipUsageRecords)[0] == PASS,
+                        "IP usage record list validation failed")
+
+        self.assertTrue(float(ipUsageRecords[0].rawusage) > 0,
+                        "Raw usage not started for ip address")
+
+        response = self.listUsageRecords(usagetype=11, sleep=False)
+        self.assertEqual(response[0], PASS, response[1])
+        usageRecords = response[1]
+
+        lbRule_1_UsageRecords = [record for record in usageRecords
+                                 if lbrule_1.id == record.usageid]
+
+        self.assertTrue(validateList(lbRule_1_UsageRecords)[0] == PASS,
+                        "LB rule usage record list validation failed")
+
+        self.assertTrue(float(lbRule_1_UsageRecords[0].rawusage) > 0,
+                        "LB usage not started for nat rule")
+
+        lbRule_2_UsageRecords = [record for record in usageRecords
+                                 if lbrule_2.id == record.usageid]
+
+        self.assertTrue(validateList(lbRule_2_UsageRecords)[0] == PASS,
+                        "LB rule usage record list validation failed")
+
+        self.assertTrue(float(lbRule_2_UsageRecords[0].rawusage) > 0,
+                        "LB usage not started for nat rule")
+
+        # Step 5
+        EgressFireWallRule.create(
+            self.userapiclient,
+            networkid=virtual_machine.nic[0].networkid,
+            protocol=self.testdata["icmprule"]["protocol"],
+            type=self.testdata["icmprule"]["icmptype"],
+            code=self.testdata["icmprule"]["icmpcode"],
+            cidrlist=self.testdata["icmprule"]["cidrlist"])
+
+        lbrule_1.assign(self.userapiclient, [virtual_machine])
+
+        ssh_client = virtual_machine.get_ssh_client(
+            ipaddress=public_ip_1.ipaddress.ipaddress,
+            port=publicport
+        )
+
+        # Step 6
+        res = ssh_client.execute("ping -c 1 www.google.com")
+        self.assertEqual(
+            str(res).count("1 received"),
+            1,
+            "Ping to outside world from VM should be successful"
+        )
+
+        # Verifying usage for bytes received - START
+        routers = list_routers(
+            self.apiclient,
+            networkid=virtual_machine.nic[0].networkid,
+            listall=True
+        )
+        self.assertEqual(
+            validateList(routers)[0],
+            PASS,
+            "Routers list validation failed")
+        router = routers[0]
+        result = self.getCommandResultFromRouter(
+            router,
+            "iptables -L NETWORK_STATS -n -v -x")
+
+        self.debug("iptables -L NETWORK_STATS -n -v -x: %s" % result)
+
+        bytesReceivedIptableRows = [record for record in result if
+                                    "eth2   eth0" in record]
+        self.debug("bytes received rows: %s" % bytesReceivedIptableRows)
+        bytesReceivedOnRouter = sum(
+            int(record[1]) for record in [x.split() for x in bytesReceivedIptableRows])
+
+        self.debug(
+            "Bytes received extracted from router: %s" %
+            bytesReceivedOnRouter)
+
+        # Verify that bytes received in usage are equal to
+        # as shown on router
+        response = self.listUsageRecords(usagetype=5)
+        self.assertEqual(response[0], PASS, response[1])
+        bytesReceivedUsage = sum(
+            int(record.rawusage) for record in response[1])
+
+        self.assertTrue(bytesReceivedUsage ==
+                        bytesReceivedOnRouter,
+                        "Total bytes received usage should be \
+                        equal to bytes received on router")
+
+        # Verifying usage for bytes received - END
+
+        lbrule_1.delete(self.userapiclient)
+        # Step 7 Verify that usage is stopped for the LB rule
+
+        response = self.listUsageRecords(usagetype=11)
+        self.assertEqual(response[0], PASS, response[1])
+        lbUsageRecords = response[1]
+
+        usageForLbRuleAfterDeletion_t1 = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in lbUsageRecords
+                if lbrule_1.id == record.usageid])
+
+        response = self.listUsageRecords(usagetype=11)
+        self.assertEqual(response[0], PASS, response[1])
+        lbUsageRecords = response[1]
+
+        usageForLbRuleAfterDeletion_t2 = sum(
+            float(
+                record.rawusage) for record in [
+                record for record in lbUsageRecords
+                if lbrule_1.id == record.usageid])
+
+        self.assertTrue(usageForLbRuleAfterDeletion_t1 ==
+                        usageForLbRuleAfterDeletion_t2,
+                        "usage for LB rule after deletion should remain the same\
+                        after specific intervals of time")
+
+        qresultset = self.dbclient.execute(
+            "select id from account where account_name = '%s';"
+            % self.account.name
+        )
+        accountid = qresultset[0][0]
+        self.debug("accountid: %s" % accountid)
+
+        qresultset = self.dbclient.execute(
+            "select current_bytes_sent, current_bytes_received  from user_statistics where account_id = '%s';" %
+            accountid,
+            db="cloud_usage")[0]
+
+        currentBytesSentBeforeRouterStop = qresultset[0]
+        currentBytesReceivedBeforeRouterStop = qresultset[1]
+
+        self.debug(currentBytesSentBeforeRouterStop)
+        self.debug(currentBytesReceivedBeforeRouterStop)
+
+        # Step 8
+        routers = Router.list(
+            self.apiclient,
+            account=self.account.name,
+            domainid=self.account.domainid,
+        )
+
+        self.assertEqual(
+            validateList(routers)[0],
+            PASS,
+            "Check for list routers response return valid data"
+        )
+        router = routers[0]
+
+        # Stop the router
+        Router.stop(
+            self.apiclient,
+            id=router.id
+        )
+
+        response = verifyRouterState(
+            self.apiclient,
+            router.id,
+            "stopped")
+        self.assertEqual(response[0], PASS, response[1])
+
+        qresultset = self.dbclient.execute(
+            "select current_bytes_sent, current_bytes_received, net_bytes_sent, net_bytes_received from user_statistics where account_id = '%s';" %
+            accountid,
+            db="cloud_usage")[0]
+
+        currentBytesSentAfterRouterStop = int(qresultset[0])
+        currentBytesReceivedAfterRouterStop = int(qresultset[1])
+        netBytesSentAfterRouterStop = int(qresultset[0])
+        netBytesReceivedAfterRouterStop = int(qresultset[1])
+
+        self.debug(currentBytesSentAfterRouterStop)
+        self.debug(currentBytesReceivedAfterRouterStop)
+        self.debug(netBytesSentAfterRouterStop)
+        self.debug(netBytesReceivedAfterRouterStop)
+
+        self.assertTrue(
+            (currentBytesSentAfterRouterStop +
+             currentBytesReceivedAfterRouterStop) == 0,
+            "Current bytes should be 0")
+
+        self.assertTrue(
+            (currentBytesSentBeforeRouterStop +
+             currentBytesReceivedBeforeRouterStop) == (
+                netBytesSentAfterRouterStop +
+                netBytesReceivedAfterRouterStop),
+            "current bytes should be moved to net bytes")
+
+        # TODO: Verify iptables counters are reset when domR starts
+
+        # Step 9
+        # Start the router
+        Router.start(
+            self.apiclient,
+            id=router.id
+        )
+
+        response = verifyRouterState(
+            self.apiclient,
+            router.id,
+            "running")
+        self.assertEqual(response[0], PASS, response[1])
+
+        #  TODO: Verify iptables counters are reset when domR starts
+        #  Verify a diff of total (current_bytes + net_bytes) in previous
+        #  aggregation period and current period will give the network usage
+        return
+
+    @attr(tags=["advanced"], required_hardware="true")
+    def test_05_positive_tests_usage(self):
+        """ Positive test for usage test path T61 - T62
+        Steps:
+        # 1. Deploy a VM
+        # 2. Take Vm snapshot and verify usage is generated for VM snapshot
+        # 3. Delete VM snapshot and verify that usage stops
+        """
+
+        time.sleep(180)
+
+        if self.hypervisor.lower() in ['kvm', 'hyperv']:
+            self.skipTest("This feature is not supported on %s" %
+                          self.hypervisor)
+
+        # Step 1
+        # Create VM in account
+        virtual_machine = VirtualMachine.create(
+            self.userapiclient,
+            self.testdata["small"],
+            templateid=self.template.id,
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            serviceofferingid=self.service_offering.id,
+            zoneid=self.zone.id
+        )
+
+        # Step 2
+        vmsnapshot = VmSnapshot.create(
+            self.userapiclient,
+            virtual_machine.id)
+
+        response = self.listUsageRecords(usagetype=25)
+        self.assertEqual(response[0], PASS, response[1])
+
+        # Step 3
+        VmSnapshot.deleteVMSnapshot(
+            self.userapiclient,
+            vmsnapshot.id
+        )
+
+        response = self.listUsageRecords(usagetype=25)
+        self.assertEqual(response[0], PASS, response[1])
+        vmSnapshotUsageRecords_t1 = response[1]
+
+        vmSnapshotUsage_t1 = sum(float(record.rawusage)
+                                 for record in vmSnapshotUsageRecords_t1)
+
+        response = self.listUsageRecords(usagetype=25)
+        self.assertEqual(response[0], PASS, response[1])
+        vmSnapshotUsageRecords_t2 = response[1]
+
+        vmSnapshotUsage_t2 = sum(float(record.rawusage)
+                                 for record in vmSnapshotUsageRecords_t2)
+
+        self.debug(vmSnapshotUsage_t1)
+        self.debug(vmSnapshotUsage_t2)
+
+        self.assertEqual(
+            vmSnapshotUsage_t1,
+            vmSnapshotUsage_t2,
+            "VmSnapshot usage should remain the same\
+            

<TRUNCATED>

Mime
View raw message