Teach simple_tenant_usage about cells

Related to blueprint cells-aware-api

Change-Id: Icd5e46e0276df6cf7ffbbb57abb1dddc46678e11
This commit is contained in:
Dan Smith 2017-03-03 10:50:41 -08:00
parent 8dbefb4a92
commit f061579f00
2 changed files with 67 additions and 13 deletions

View File

@ -26,6 +26,7 @@ from nova.api.openstack.compute.views import usages as usages_view
from nova.api.openstack import extensions
from nova.api.openstack import wsgi
import nova.conf
from nova import context as nova_context
from nova import exception
from nova.i18n import _
from nova import objects
@ -104,13 +105,43 @@ class SimpleTenantUsageController(wsgi.Controller):
return flavor_ref
def _get_instances_all_cells(self, context, period_start, period_stop,
tenant_id, limit, marker):
all_instances = []
cells = objects.CellMappingList.get_all(context)
for cell in cells:
with nova_context.target_cell(context, cell):
try:
instances = (
objects.InstanceList.get_active_by_window_joined(
context, period_start, period_stop, tenant_id,
expected_attrs=['flavor'], limit=limit,
marker=marker))
except exception.MarkerNotFound:
# NOTE(danms): We need to keep looking through the later
# cells to find the marker
continue
all_instances.extend(instances)
# NOTE(danms): We must have found a marker if we had one,
# so make sure we don't require a marker in the next cell
marker = None
if limit:
limit -= len(instances)
if limit <= 0:
break
if marker is not None and len(all_instances) == 0:
# NOTE(danms): If we did not find the marker in any cell,
# mimic the db_api behavior here
raise exception.MarkerNotFound(marker=marker)
return all_instances
def _tenant_usages_for_period(self, context, period_start, period_stop,
tenant_id=None, detailed=True, limit=None,
marker=None):
instances = objects.InstanceList.get_active_by_window_joined(
context, period_start, period_stop, tenant_id,
expected_attrs=['flavor'], limit=limit, marker=marker)
instances = self._get_instances_all_cells(context, period_start,
period_stop, tenant_id,
limit, marker)
rval = {}
flavors = {}
all_server_usages = []

View File

@ -119,6 +119,8 @@ class SimpleTenantUsageTestV21(test.TestCase):
self.alt_user_context = context.RequestContext('fakeadmin_0',
'faketenant_1',
is_admin=False)
self.num_cells = len(objects.CellMappingList.get_all(
self.admin_context))
def _test_verify_index(self, start, stop, limit=None):
url = '?start=%s&end=%s'
@ -131,13 +133,23 @@ class SimpleTenantUsageTestV21(test.TestCase):
res_dict = self.controller.index(req)
usages = res_dict['tenant_usages']
if limit:
num = 1
else:
# NOTE(danms): We call our fake data mock once per cell,
# and the default fixture has two cells (cell0 and cell1),
# so all our math will be doubled.
num = self.num_cells
for i in range(TENANTS):
self.assertEqual(SERVERS * HOURS, int(usages[i]['total_hours']))
self.assertEqual(SERVERS * (ROOT_GB + EPHEMERAL_GB) * HOURS,
self.assertEqual(SERVERS * HOURS * num,
int(usages[i]['total_hours']))
self.assertEqual(SERVERS * (ROOT_GB + EPHEMERAL_GB) * HOURS * num,
int(usages[i]['total_local_gb_usage']))
self.assertEqual(SERVERS * MEMORY_MB * HOURS,
self.assertEqual(SERVERS * MEMORY_MB * HOURS * num,
int(usages[i]['total_memory_mb_usage']))
self.assertEqual(SERVERS * VCPUS * HOURS,
self.assertEqual(SERVERS * VCPUS * HOURS * num,
int(usages[i]['total_vcpus_usage']))
self.assertFalse(usages[i].get('server_usages'))
@ -216,9 +228,17 @@ class SimpleTenantUsageTestV21(test.TestCase):
req.environ['nova.context'] = self.user_context
res_dict = self.controller.show(req, tenant_id)
if limit:
num = 1
else:
# NOTE(danms): We call our fake data mock once per cell,
# and the default fixture has two cells (cell0 and cell1),
# so all our math will be doubled.
num = self.num_cells
usage = res_dict['tenant_usage']
servers = usage['server_usages']
self.assertEqual(TENANTS * SERVERS, len(usage['server_usages']))
self.assertEqual(TENANTS * SERVERS * num, len(usage['server_usages']))
server_uuids = [getattr(uuids, 'instance_%d' % x)
for x in range(SERVERS)]
for j in range(SERVERS):
@ -292,10 +312,12 @@ class SimpleTenantUsageTestV40(SimpleTenantUsageTestV21):
version = '2.40'
def test_next_links_show(self):
self._test_verify_show(START, STOP, limit=SERVERS * TENANTS)
self._test_verify_show(START, STOP,
limit=SERVERS * TENANTS)
def test_next_links_index(self):
self._test_verify_index(START, STOP, limit=SERVERS * TENANTS)
self._test_verify_index(START, STOP,
limit=SERVERS * TENANTS)
class SimpleTenantUsageLimitsTestV21(test.TestCase):
@ -311,7 +333,7 @@ class SimpleTenantUsageLimitsTestV21(test.TestCase):
return fakes.HTTPRequest.blank(url, version=self.version)
def assert_limit(self, mock_get, limit):
mock_get.assert_called_once_with(
mock_get.assert_called_with(
mock.ANY, mock.ANY, mock.ANY, mock.ANY, expected_attrs=['flavor'],
limit=1000, marker=None)
@ -332,7 +354,8 @@ class SimpleTenantUsageLimitsTestV240(SimpleTenantUsageLimitsTestV21):
version = '2.40'
def assert_limit_and_marker(self, mock_get, limit, marker):
mock_get.assert_called_once_with(
# NOTE(danms): Make sure we called at least once with the marker
mock_get.assert_any_call(
mock.ANY, mock.ANY, mock.ANY, mock.ANY, expected_attrs=['flavor'],
limit=3, marker=marker)