Fix simple_tenant_usage's handing of future end times
Fixes bug #1043999
simple_tenant_usage returns the usage in the range between the supplied
start and end query parameters. The _hours_for() method calculates the
number of hours the instance was running in this range, even if the end time
is in the future.
By default, python-novaclient requests usage between 4 weeks ago and tomorrow.
This means we a report which accounts for 24 hours of extra running time for
each currently running instance. Fix this by clamping the period of the
returned report at the current time.
Change-Id: I61c211fd85b729aaeaac6ef24644ee19eb5bb6b0
(cherry picked from commit 869443f41c)
This commit is contained in:
1
Authors
1
Authors
@@ -172,6 +172,7 @@ Rick Clark <rick@openstack.org>
|
||||
Rick Harris <rconradharris@gmail.com>
|
||||
Rob Kost <kost@isi.edu>
|
||||
Robert Esker <esker@netapp.com>
|
||||
RongzeZhu <zrzhit@gmail.com>
|
||||
Russell Bryant <rbryant@redhat.com>
|
||||
Russell Sim <russell.sim@gmail.com>
|
||||
Ryan Lane <rlane@wikimedia.org>
|
||||
|
||||
@@ -24,6 +24,7 @@ from nova.api.openstack import xmlutil
|
||||
from nova.compute import api
|
||||
from nova import exception
|
||||
from nova import flags
|
||||
from nova import utils
|
||||
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
@@ -217,6 +218,9 @@ class SimpleTenantUsageController(object):
|
||||
authorize_list(context)
|
||||
|
||||
(period_start, period_stop, detailed) = self._get_datetime_range(req)
|
||||
now = utils.utcnow()
|
||||
if period_stop > now:
|
||||
period_stop = now
|
||||
usages = self._tenant_usages_for_period(context,
|
||||
period_start,
|
||||
period_stop,
|
||||
@@ -232,6 +236,9 @@ class SimpleTenantUsageController(object):
|
||||
authorize_show(context, {'project_id': tenant_id})
|
||||
|
||||
(period_start, period_stop, ignore) = self._get_datetime_range(req)
|
||||
now = utils.utcnow()
|
||||
if period_stop > now:
|
||||
period_stop = now
|
||||
usage = self._tenant_usages_for_period(context,
|
||||
period_start,
|
||||
period_stop,
|
||||
|
||||
@@ -28,6 +28,7 @@ from nova.compute import api
|
||||
from nova import context
|
||||
from nova import flags
|
||||
from nova import test
|
||||
from nova import utils
|
||||
from nova.tests.api.openstack import fakes
|
||||
|
||||
|
||||
@@ -40,8 +41,9 @@ ROOT_GB = 10
|
||||
EPHEMERAL_GB = 20
|
||||
MEMORY_MB = 1024
|
||||
VCPUS = 2
|
||||
STOP = datetime.datetime.utcnow()
|
||||
START = STOP - datetime.timedelta(hours=HOURS)
|
||||
NOW = utils.utcnow()
|
||||
START = NOW - datetime.timedelta(hours=HOURS)
|
||||
STOP = NOW
|
||||
|
||||
|
||||
def fake_instance_type_get(self, context, instance_type_id):
|
||||
@@ -91,10 +93,10 @@ class SimpleTenantUsageTest(test.TestCase):
|
||||
'faketenant_1',
|
||||
is_admin=False)
|
||||
|
||||
def test_verify_index(self):
|
||||
def _test_verify_index(self, start, stop):
|
||||
req = webob.Request.blank(
|
||||
'/v2/faketenant_0/os-simple-tenant-usage?start=%s&end=%s' %
|
||||
(START.isoformat(), STOP.isoformat()))
|
||||
(start.isoformat(), stop.isoformat()))
|
||||
req.method = "GET"
|
||||
req.headers["content-type"] = "application/json"
|
||||
|
||||
@@ -115,6 +117,20 @@ class SimpleTenantUsageTest(test.TestCase):
|
||||
SERVERS * VCPUS * HOURS)
|
||||
self.assertFalse(usages[i].get('server_usages'))
|
||||
|
||||
def test_verify_index(self):
|
||||
self._test_verify_index(START, STOP)
|
||||
|
||||
def test_verify_index_future_end_time(self):
|
||||
future = NOW + datetime.timedelta(hours=HOURS)
|
||||
self._test_verify_index(START, future)
|
||||
|
||||
def test_verify_show(self):
|
||||
self._test_verify_show(START, STOP)
|
||||
|
||||
def test_verify_show_future_end_time(self):
|
||||
future = NOW + datetime.timedelta(hours=HOURS)
|
||||
self._test_verify_show(START, future)
|
||||
|
||||
def test_verify_detailed_index(self):
|
||||
req = webob.Request.blank(
|
||||
'/v2/faketenant_0/os-simple-tenant-usage?'
|
||||
@@ -133,11 +149,11 @@ class SimpleTenantUsageTest(test.TestCase):
|
||||
for j in xrange(SERVERS):
|
||||
self.assertEqual(int(servers[j]['hours']), HOURS)
|
||||
|
||||
def test_verify_show(self):
|
||||
def _test_verify_show(self, start, stop):
|
||||
req = webob.Request.blank(
|
||||
'/v2/faketenant_0/os-simple-tenant-usage/'
|
||||
'faketenant_0?start=%s&end=%s' %
|
||||
(START.isoformat(), STOP.isoformat()))
|
||||
(start.isoformat(), stop.isoformat()))
|
||||
req.method = "GET"
|
||||
req.headers["content-type"] = "application/json"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user