summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaushik Chandrashekar <kaushik.chandrashekar@rackspace.com>2013-04-22 06:26:32 -0500
committerKaushik Chandrashekar <kaushik.chandrashekar@rackspace.com>2013-06-05 12:52:55 -0500
commitb27a6cb39968ebd7a1d55322779dc862682d1364 (patch)
tree918ce53ebeabfd26337de26dbb42f9675ad50a06
parent09adc96f8fdf923a2aa377f408b956cb8fba3097 (diff)
downloadnova-b27a6cb39968ebd7a1d55322779dc862682d1364.tar.gz
nova-b27a6cb39968ebd7a1d55322779dc862682d1364.tar.xz
nova-b27a6cb39968ebd7a1d55322779dc862682d1364.zip
API to get the Cell Capacity
The total RAM and the available RAM are stored in memory of CellStateManager. This API gets the available slots per flavor for a given cell. Implements: blueprint get-cell-free-ram Change-Id: I2a6dbb8835cad04f3ee058c3012490782d7c8e67
-rw-r--r--doc/api_samples/all_extensions/extensions-get-resp.json8
-rw-r--r--doc/api_samples/all_extensions/extensions-get-resp.xml3
-rw-r--r--doc/api_samples/os-cell-capacities/cells-capacities-resp.json18
-rw-r--r--doc/api_samples/os-cell-capacities/cells-capacities-resp.xml19
-rw-r--r--nova/api/openstack/compute/contrib/cell_capacities.py27
-rw-r--r--nova/api/openstack/compute/contrib/cells.py58
-rw-r--r--nova/cells/manager.py5
-rw-r--r--nova/cells/rpcapi.py6
-rw-r--r--nova/cells/state.py9
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_cells.py72
-rw-r--r--nova/tests/cells/test_cells_manager.py12
-rw-r--r--nova/tests/cells/test_cells_rpcapi.py10
-rw-r--r--nova/tests/cells/test_cells_state_manager.py48
-rw-r--r--nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl8
-rw-r--r--nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl3
-rw-r--r--nova/tests/integrated/api_samples/os-cell-capacities/cells-capacities-resp.json.tpl18
-rw-r--r--nova/tests/integrated/api_samples/os-cell-capacities/cells-capacities-resp.xml.tpl19
-rw-r--r--nova/tests/integrated/test_api_samples.py49
18 files changed, 382 insertions, 10 deletions
diff --git a/doc/api_samples/all_extensions/extensions-get-resp.json b/doc/api_samples/all_extensions/extensions-get-resp.json
index ace0dc9bb..b4323b097 100644
--- a/doc/api_samples/all_extensions/extensions-get-resp.json
+++ b/doc/api_samples/all_extensions/extensions-get-resp.json
@@ -161,6 +161,14 @@
"updated": "2011-09-21T00:00:00+00:00"
},
{
+ "alias": "os-cell-capacities",
+ "description": "Adding functionality to get cell capacities.",
+ "links": [],
+ "name": "CellCapacities",
+ "namespace": "http://docs.openstack.org/compute/ext/cell_capacities/api/v1.1",
+ "updated": "2013-05-27T00:00:00+00:00"
+ },
+ {
"alias": "os-certificates",
"description": "Certificates support.",
"links": [],
diff --git a/doc/api_samples/all_extensions/extensions-get-resp.xml b/doc/api_samples/all_extensions/extensions-get-resp.xml
index 23d8b30d7..26361e719 100644
--- a/doc/api_samples/all_extensions/extensions-get-resp.xml
+++ b/doc/api_samples/all_extensions/extensions-get-resp.xml
@@ -68,6 +68,9 @@
listing neighbor cells, and getting the capabilities of the local cell.
</description>
</extension>
+ <extension alias="os-cell-capacities" updated="2013-05-27T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/cell_capacities/api/v1.1" name="CellCapacities">
+ <description>Adds functionality to get cell capacities.</description>
+ </extension>
<extension alias="os-certificates" updated="2012-01-19T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/certificates/api/v1.1" name="Certificates">
<description>Certificates support.</description>
</extension>
diff --git a/doc/api_samples/os-cell-capacities/cells-capacities-resp.json b/doc/api_samples/os-cell-capacities/cells-capacities-resp.json
new file mode 100644
index 000000000..b926f8d1d
--- /dev/null
+++ b/doc/api_samples/os-cell-capacities/cells-capacities-resp.json
@@ -0,0 +1,18 @@
+{
+ "cell": {
+ "capacities": {
+ "ram_free": {
+ "units_by_mb": {
+ "8192": 0, "512": 13, "4096": 1, "2048": 3, "16384": 0
+ },
+ "total_mb": 7680
+ },
+ "disk_free": {
+ "units_by_mb": {
+ "81920": 11, "20480": 46, "40960": 23, "163840": 5, "0": 0
+ },
+ "total_mb": 1052672
+ }
+ }
+ }
+}
diff --git a/doc/api_samples/os-cell-capacities/cells-capacities-resp.xml b/doc/api_samples/os-cell-capacities/cells-capacities-resp.xml
new file mode 100644
index 000000000..63672b00b
--- /dev/null
+++ b/doc/api_samples/os-cell-capacities/cells-capacities-resp.xml
@@ -0,0 +1,19 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<cell xmlns="http://docs.rackspacecloud.com/servers/api/v1.0">
+ <capacities>
+ <ram_free total_mb="7680">
+ <unit_by_mb unit="0" mb="8192"/>
+ <unit_by_mb unit="13" mb="512"/>
+ <unit_by_mb unit="1" mb="4096"/>
+ <unit_by_mb unit="3" mb="2048"/>
+ <unit_by_mb unit="0" mb="16384"/>
+ </ram_free>
+ <disk_free total_mb="1052672">
+ <unit_by_mb unit="11" mb="81920"/>
+ <unit_by_mb unit="46" mb="20480"/>
+ <unit_by_mb unit="23" mb="40960"/>
+ <unit_by_mb unit="5" mb="163840"/>
+ <unit_by_mb unit="0" mb="0"/>
+ </disk_free>
+ </capacities>
+</cell>
diff --git a/nova/api/openstack/compute/contrib/cell_capacities.py b/nova/api/openstack/compute/contrib/cell_capacities.py
new file mode 100644
index 000000000..ae8b42336
--- /dev/null
+++ b/nova/api/openstack/compute/contrib/cell_capacities.py
@@ -0,0 +1,27 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# Copyright 2013 Rackspace Hosting
+#
+# Licensed 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
+
+from nova.api.openstack import extensions
+
+
+class Cell_capacities(extensions.ExtensionDescriptor):
+ """Adding functionality to get cell capacities."""
+
+ name = "CellCapacities"
+ alias = "os-cell-capacities"
+ namespace = ("http://docs.openstack.org/compute/ext/"
+ "cell_capacities/api/v1.1")
+ updated = "2013-05-27T00:00:00+00:00"
diff --git a/nova/api/openstack/compute/contrib/cells.py b/nova/api/openstack/compute/contrib/cells.py
index 03597ff0e..4e809d70e 100644
--- a/nova/api/openstack/compute/contrib/cells.py
+++ b/nova/api/openstack/compute/contrib/cells.py
@@ -52,8 +52,33 @@ def make_cell(elem):
cap = xmlutil.SubTemplateElement(caps, xmlutil.Selector(0),
selector=xmlutil.get_items)
cap.text = 1
+ make_capacity(elem)
+def make_capacity(cell):
+
+ def get_units_by_mb(capacity_info):
+ return capacity_info['units_by_mb'].items()
+
+ capacity = xmlutil.SubTemplateElement(cell, 'capacities',
+ selector='capacities')
+
+ ram_free = xmlutil.SubTemplateElement(capacity, 'ram_free',
+ selector='ram_free')
+ ram_free.set('total_mb', 'total_mb')
+ unit_by_mb = xmlutil.SubTemplateElement(ram_free, 'unit_by_mb',
+ selector=get_units_by_mb)
+ unit_by_mb.set('mb', 0)
+ unit_by_mb.set('unit', 1)
+
+ disk_free = xmlutil.SubTemplateElement(capacity, 'disk_free',
+ selector='disk_free')
+ disk_free.set('total_mb', 'total_mb')
+ unit_by_mb = xmlutil.SubTemplateElement(disk_free, 'unit_by_mb',
+ selector=get_units_by_mb)
+ unit_by_mb.set('mb', 0)
+ unit_by_mb.set('unit', 1)
+
cell_nsmap = {None: wsgi.XMLNS_V10}
@@ -123,9 +148,10 @@ def _scrub_cell(cell, detail=False):
class Controller(object):
"""Controller for Cell resources."""
- def __init__(self):
+ def __init__(self, ext_mgr):
self.compute_api = compute.API()
self.cells_rpcapi = cells_rpcapi.CellsAPI()
+ self.ext_mgr = ext_mgr
def _get_cells(self, ctxt, req, detail=False):
"""Return all cells."""
@@ -168,6 +194,25 @@ class Controller(object):
return dict(cell=cell)
@wsgi.serializers(xml=CellTemplate)
+ def capacities(self, req, id=None):
+ """Return capacities for a given cell or all cells."""
+ # TODO(kaushikc): return capacities as a part of cell info and
+ # cells detail calls in v3, along with capabilities
+ if not self.ext_mgr.is_loaded('os-cell-capacities'):
+ raise exc.HTTPNotFound()
+
+ context = req.environ['nova.context']
+ authorize(context)
+ try:
+ capacities = self.cells_rpcapi.get_capacities(context,
+ cell_name=id)
+ except exception.CellNotFound:
+ msg = (_("Cell %(id)s not found.") % {'id': id})
+ raise exc.HTTPNotFound(explanation=msg)
+
+ return dict(cell={"capacities": capacities})
+
+ @wsgi.serializers(xml=CellTemplate)
def show(self, req, id):
"""Return data about the given cell name. 'id' is a cell name."""
context = req.environ['nova.context']
@@ -283,15 +328,20 @@ class Cells(extensions.ExtensionDescriptor):
name = "Cells"
alias = "os-cells"
namespace = "http://docs.openstack.org/compute/ext/cells/api/v1.1"
- updated = "2011-09-21T00:00:00+00:00"
+ updated = "2013-05-14T00:00:00+00:00"
def get_resources(self):
coll_actions = {
'detail': 'GET',
'info': 'GET',
'sync_instances': 'POST',
- }
+ 'capacities': 'GET',
+ }
+ memb_actions = {
+ 'capacities': 'GET',
+ }
res = extensions.ResourceExtension('os-cells',
- Controller(), collection_actions=coll_actions)
+ Controller(self.ext_mgr), collection_actions=coll_actions,
+ member_actions=memb_actions)
return [res]
diff --git a/nova/cells/manager.py b/nova/cells/manager.py
index ba909c034..f776c542e 100644
--- a/nova/cells/manager.py
+++ b/nova/cells/manager.py
@@ -64,7 +64,7 @@ class CellsManager(manager.Manager):
Scheduling requests get passed to the scheduler class.
"""
- RPC_API_VERSION = '1.8'
+ RPC_API_VERSION = '1.9'
def __init__(self, *args, **kwargs):
# Mostly for tests.
@@ -387,3 +387,6 @@ class CellsManager(manager.Manager):
instance['cell_name'], instance_uuid, console_port,
console_type)
return response.value_or_raise()
+
+ def get_capacities(self, ctxt, cell_name):
+ return self.state_manager.get_capacities(cell_name)
diff --git a/nova/cells/rpcapi.py b/nova/cells/rpcapi.py
index 4a45af255..dd757c818 100644
--- a/nova/cells/rpcapi.py
+++ b/nova/cells/rpcapi.py
@@ -51,6 +51,7 @@ class CellsAPI(rpc_proxy.RpcProxy):
1.6 - Adds consoleauth_delete_tokens() and validate_console_port()
1.7 - Adds service_update()
1.8 - Adds build_instances(), deprecates schedule_run_instance()
+ 1.9 - Adds get_capacities()
'''
BASE_RPC_API_VERSION = '1.0'
@@ -292,3 +293,8 @@ class CellsAPI(rpc_proxy.RpcProxy):
console_port=console_port,
console_type=console_type),
version='1.6')
+
+ def get_capacities(self, ctxt, cell_name=None):
+ return self.call(ctxt,
+ self.make_msg('get_capacities', cell_name=cell_name),
+ version='1.9')
diff --git a/nova/cells/state.py b/nova/cells/state.py
index defa897a9..37813d581 100644
--- a/nova/cells/state.py
+++ b/nova/cells/state.py
@@ -25,6 +25,7 @@ from oslo.config import cfg
from nova.cells import rpc_driver
from nova import context
from nova.db import base
+from nova import exception
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
from nova import utils
@@ -361,3 +362,11 @@ class CellStateManager(base.Base):
for cell in self.child_cells.values():
self._add_to_dict(capacities, cell.capacities)
return capacities
+
+ @sync_from_db
+ def get_capacities(self, cell_name=None):
+ if not cell_name or cell_name == self.my_cell_state.name:
+ return self.get_our_capacities()
+ if cell_name in self.child_cells:
+ return self.child_cells[cell_name].capacities
+ raise exception.CellNotFound(cell_name=cell_name)
diff --git a/nova/tests/api/openstack/compute/contrib/test_cells.py b/nova/tests/api/openstack/compute/contrib/test_cells.py
index bf6bff27c..a9e77693e 100644
--- a/nova/tests/api/openstack/compute/contrib/test_cells.py
+++ b/nova/tests/api/openstack/compute/contrib/test_cells.py
@@ -19,6 +19,7 @@ from lxml import etree
from webob import exc
from nova.api.openstack.compute.contrib import cells as cells_ext
+from nova.api.openstack import extensions
from nova.api.openstack import xmlutil
from nova.cells import rpcapi as cells_rpcapi
from nova import context
@@ -87,7 +88,8 @@ class CellsTest(test.TestCase):
self.stubs.Set(cells_rpcapi.CellsAPI, 'get_cell_info_for_neighbors',
fake_cells_api_get_all_cell_info)
- self.controller = cells_ext.Controller()
+ self.ext_mgr = self.mox.CreateMock(extensions.ExtensionManager)
+ self.controller = cells_ext.Controller(self.ext_mgr)
self.context = context.get_admin_context()
def _get_request(self, resource):
@@ -281,6 +283,74 @@ class CellsTest(test.TestCase):
self.assertEqual(cell_caps['cap1'], 'a;b')
self.assertEqual(cell_caps['cap2'], 'c;d')
+ def test_show_capacities(self):
+ self.ext_mgr.is_loaded('os-cell-capacities').AndReturn(True)
+ self.mox.StubOutWithMock(self.controller.cells_rpcapi,
+ 'get_capacities')
+ response = {"ram_free":
+ {"units_by_mb": {"8192": 0, "512": 13,
+ "4096": 1, "2048": 3, "16384": 0},
+ "total_mb": 7680},
+ "disk_free":
+ {"units_by_mb": {"81920": 11, "20480": 46,
+ "40960": 23, "163840": 5, "0": 0},
+ "total_mb": 1052672}
+ }
+ self.controller.cells_rpcapi.\
+ get_capacities(self.context, cell_name=None).AndReturn(response)
+ self.mox.ReplayAll()
+ req = self._get_request("cells/capacities")
+ req.environ["nova.context"] = self.context
+ res_dict = self.controller.capacities(req)
+ self.assertEqual(response, res_dict['cell']['capacities'])
+
+ def test_show_capacity_fails_with_non_admin_context(self):
+ self.ext_mgr.is_loaded('os-cell-capacities').AndReturn(True)
+ rules = {"compute_extension:cells": "is_admin:true"}
+ self.policy.set_rules(rules)
+
+ self.mox.ReplayAll()
+ req = self._get_request("cells/capacities")
+ req.environ["nova.context"] = self.context
+ req.environ["nova.context"].is_admin = False
+ self.assertRaises(exception.PolicyNotAuthorized,
+ self.controller.capacities, req)
+
+ def test_show_capacities_for_invalid_cell(self):
+ self.ext_mgr.is_loaded('os-cell-capacities').AndReturn(True)
+ self.mox.StubOutWithMock(self.controller.cells_rpcapi,
+ 'get_capacities')
+ self.controller.cells_rpcapi. \
+ get_capacities(self.context, cell_name="invalid_cell").AndRaise(
+ exception.CellNotFound(cell_name="invalid_cell"))
+ self.mox.ReplayAll()
+ req = self._get_request("cells/invalid_cell/capacities")
+ req.environ["nova.context"] = self.context
+ self.assertRaises(exc.HTTPNotFound,
+ self.controller.capacities, req, "invalid_cell")
+
+ def test_show_capacities_for_cell(self):
+ self.ext_mgr.is_loaded('os-cell-capacities').AndReturn(True)
+ self.mox.StubOutWithMock(self.controller.cells_rpcapi,
+ 'get_capacities')
+ response = {"ram_free":
+ {"units_by_mb": {"8192": 0, "512": 13,
+ "4096": 1, "2048": 3, "16384": 0},
+ "total_mb": 7680},
+ "disk_free":
+ {"units_by_mb": {"81920": 11, "20480": 46,
+ "40960": 23, "163840": 5, "0": 0},
+ "total_mb": 1052672}
+ }
+ self.controller.cells_rpcapi.\
+ get_capacities(self.context, cell_name='cell_name').\
+ AndReturn(response)
+ self.mox.ReplayAll()
+ req = self._get_request("cells/capacities")
+ req.environ["nova.context"] = self.context
+ res_dict = self.controller.capacities(req, 'cell_name')
+ self.assertEqual(response, res_dict['cell']['capacities'])
+
def test_sync_instances(self):
call_info = {}
diff --git a/nova/tests/cells/test_cells_manager.py b/nova/tests/cells/test_cells_manager.py
index 543ff66e7..4e35cd818 100644
--- a/nova/tests/cells/test_cells_manager.py
+++ b/nova/tests/cells/test_cells_manager.py
@@ -53,6 +53,7 @@ class CellsManagerClassTestCase(test.TestCase):
self.our_cell = 'grandchild-cell1'
self.cells_manager = fakes.get_cells_manager(self.our_cell)
self.msg_runner = self.cells_manager.msg_runner
+ self.state_manager = fakes.get_state_manager(self.our_cell)
self.driver = self.cells_manager.driver
self.ctxt = 'fake_context'
@@ -513,6 +514,17 @@ class CellsManagerClassTestCase(test.TestCase):
self.cells_manager.consoleauth_delete_tokens(self.ctxt,
instance_uuid=instance_uuid)
+ def test_get_capacities(self):
+ cell_name = 'cell_name'
+ response = {"ram_free":
+ {"units_by_mb": {"64": 20, "128": 10}, "total_mb": 1491}}
+ self.mox.StubOutWithMock(self.state_manager,
+ 'get_capacities')
+ self.state_manager.get_capacities(cell_name).AndReturn(response)
+ self.mox.ReplayAll()
+ self.assertEqual(response,
+ self.cells_manager.get_capacities(self.ctxt, cell_name))
+
def test_validate_console_port(self):
instance_uuid = 'fake-instance-uuid'
cell_name = 'fake-cell-name'
diff --git a/nova/tests/cells/test_cells_rpcapi.py b/nova/tests/cells/test_cells_rpcapi.py
index 172b54831..e44c0be4a 100644
--- a/nova/tests/cells/test_cells_rpcapi.py
+++ b/nova/tests/cells/test_cells_rpcapi.py
@@ -129,6 +129,16 @@ class CellsAPITestCase(test.TestCase):
self._check_result(call_info, 'build_instances',
expected_args, version=1.8)
+ def test_get_capacities(self):
+ capacity_info = {"capacity": "info"}
+ call_info = self._stub_rpc_method('call',
+ result=capacity_info)
+ result = self.cells_rpcapi.get_capacities(self.fake_context,
+ cell_name="name")
+ self._check_result(call_info, 'get_capacities',
+ {'cell_name': 'name'}, version='1.9')
+ self.assertEqual(capacity_info, result)
+
def test_instance_update_at_top(self):
fake_info_cache = {'id': 1,
'instance': 'fake_instance',
diff --git a/nova/tests/cells/test_cells_state_manager.py b/nova/tests/cells/test_cells_state_manager.py
index 078578926..03dc37ed4 100644
--- a/nova/tests/cells/test_cells_state_manager.py
+++ b/nova/tests/cells/test_cells_state_manager.py
@@ -13,11 +13,13 @@
# License for the specific language governing permissions and limitations
# under the License.
"""
-Tests For CellsStateManager
+Tests For CellStateManager
"""
from nova.cells import state
from nova import db
+from nova.db.sqlalchemy import models
+from nova import exception
from nova import test
@@ -120,9 +122,47 @@ class TestCellsStateManager(test.TestCase):
units = 2 # 2 on host 3
self.assertEqual(units, cap['disk_free']['units_by_mb'][str(sz)])
- def _capacity(self, reserve_percent):
+ def _get_state_manager(self, reserve_percent=0.0):
self.flags(reserve_percent=reserve_percent, group='cells')
+ return state.CellStateManager()
- mgr = state.CellStateManager()
- my_state = mgr.get_my_state()
+ def _capacity(self, reserve_percent):
+ state_manager = self._get_state_manager(reserve_percent)
+ my_state = state_manager.get_my_state()
return my_state.capacities
+
+
+class TestCellsGetCapacity(TestCellsStateManager):
+ def setUp(self):
+ super(TestCellsGetCapacity, self).setUp()
+ self.capacities = {"ram_free": 1234}
+ self.state_manager = self._get_state_manager()
+ cell = models.Cell(name="cell_name")
+ other_cell = models.Cell(name="other_cell_name")
+ cell.capacities = self.capacities
+ other_cell.capacities = self.capacities
+ self.stubs.Set(self.state_manager, 'child_cells',
+ {"cell_name": cell,
+ "other_cell_name": other_cell})
+
+ def test_get_cell_capacity_for_all_cells(self):
+ self.stubs.Set(self.state_manager.my_cell_state, 'capacities',
+ self.capacities)
+ capacities = self.state_manager.get_capacities()
+ self.assertEqual({"ram_free": 3702}, capacities)
+
+ def test_get_cell_capacity_for_the_parent_cell(self):
+ self.stubs.Set(self.state_manager.my_cell_state, 'capacities',
+ self.capacities)
+ capacities = self.state_manager.\
+ get_capacities(self.state_manager.my_cell_state.name)
+ self.assertEqual({"ram_free": 3702}, capacities)
+
+ def test_get_cell_capacity_for_a_cell(self):
+ self.assertEqual(self.capacities,
+ self.state_manager.get_capacities(cell_name="cell_name"))
+
+ def test_get_cell_capacity_for_non_existing_cell(self):
+ self.assertRaises(exception.CellNotFound,
+ self.state_manager.get_capacities,
+ cell_name="invalid_cell_name")
diff --git a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl
index af539c1e3..0ce9829a7 100644
--- a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl
+++ b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl
@@ -161,6 +161,14 @@
"updated": "%(timestamp)s"
},
{
+ "alias": "os-cell-capacities",
+ "description": "%(text)s",
+ "links": [],
+ "name": "CellCapacities",
+ "namespace": "http://docs.openstack.org/compute/ext/cell_capacities/api/v1.1",
+ "updated": "%(timestamp)s"
+ },
+ {
"alias": "os-certificates",
"description": "%(text)s",
"links": [],
diff --git a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl
index 205c5bc4d..9f3199418 100644
--- a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl
+++ b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl
@@ -60,6 +60,9 @@
<extension alias="os-cells" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/cells/api/v1.1" name="Cells">
<description>%(text)s</description>
</extension>
+ <extension alias="os-cell-capacities" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/cell_capacities/api/v1.1" name="CellCapacities">
+ <description>%(text)s</description>
+ </extension>
<extension alias="os-certificates" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/certificates/api/v1.1" name="Certificates">
<description>%(text)s</description>
</extension>
diff --git a/nova/tests/integrated/api_samples/os-cell-capacities/cells-capacities-resp.json.tpl b/nova/tests/integrated/api_samples/os-cell-capacities/cells-capacities-resp.json.tpl
new file mode 100644
index 000000000..b926f8d1d
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-cell-capacities/cells-capacities-resp.json.tpl
@@ -0,0 +1,18 @@
+{
+ "cell": {
+ "capacities": {
+ "ram_free": {
+ "units_by_mb": {
+ "8192": 0, "512": 13, "4096": 1, "2048": 3, "16384": 0
+ },
+ "total_mb": 7680
+ },
+ "disk_free": {
+ "units_by_mb": {
+ "81920": 11, "20480": 46, "40960": 23, "163840": 5, "0": 0
+ },
+ "total_mb": 1052672
+ }
+ }
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-cell-capacities/cells-capacities-resp.xml.tpl b/nova/tests/integrated/api_samples/os-cell-capacities/cells-capacities-resp.xml.tpl
new file mode 100644
index 000000000..63672b00b
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-cell-capacities/cells-capacities-resp.xml.tpl
@@ -0,0 +1,19 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<cell xmlns="http://docs.rackspacecloud.com/servers/api/v1.0">
+ <capacities>
+ <ram_free total_mb="7680">
+ <unit_by_mb unit="0" mb="8192"/>
+ <unit_by_mb unit="13" mb="512"/>
+ <unit_by_mb unit="1" mb="4096"/>
+ <unit_by_mb unit="3" mb="2048"/>
+ <unit_by_mb unit="0" mb="16384"/>
+ </ram_free>
+ <disk_free total_mb="1052672">
+ <unit_by_mb unit="11" mb="81920"/>
+ <unit_by_mb unit="46" mb="20480"/>
+ <unit_by_mb unit="23" mb="40960"/>
+ <unit_by_mb unit="5" mb="163840"/>
+ <unit_by_mb unit="0" mb="0"/>
+ </disk_free>
+ </capacities>
+</cell>
diff --git a/nova/tests/integrated/test_api_samples.py b/nova/tests/integrated/test_api_samples.py
index 6cd39177e..7ac0d2633 100644
--- a/nova/tests/integrated/test_api_samples.py
+++ b/nova/tests/integrated/test_api_samples.py
@@ -31,6 +31,7 @@ from nova.api.metadata import password
from nova.api.openstack.compute.contrib import coverage_ext
from nova.api.openstack.compute.contrib import fping
# Import extensions to pull in osapi_compute_extension CONF option used below.
+from nova.cells import state
from nova.cloudpipe import pipelib
from nova.compute import api as compute_api
from nova.compute import manager as compute_manager
@@ -2808,6 +2809,54 @@ class CellsSampleXmlTest(CellsSampleJsonTest):
ctype = 'xml'
+class CellsCapacitySampleJsonTest(ApiSampleTestBase):
+ extends_name = ("nova.api.openstack.compute.contrib.cells.Cells")
+ extension_name = ("nova.api.openstack.compute.contrib."
+ "cell_capacities.Cell_capacities")
+
+ def setUp(self):
+ self.flags(enable=True, db_check_interval=-1, group='cells')
+ super(CellsCapacitySampleJsonTest, self).setUp()
+ # (navneetk/kaushikc) : Mock cell capacity to avoid the capacity
+ # being calculated from the compute nodes in the environment
+ self._mock_cell_capacity()
+
+ def test_get_cell_capacity(self):
+ state_manager = state.CellStateManager()
+ my_state = state_manager.get_my_state()
+ response = self._do_get('os-cells/%s/capacities' %
+ my_state.name)
+ subs = self._get_regexes()
+ return self._verify_response('cells-capacities-resp',
+ subs, response, 200)
+
+ def test_get_all_cells_capacity(self):
+ response = self._do_get('os-cells/capacities')
+ subs = self._get_regexes()
+ return self._verify_response('cells-capacities-resp',
+ subs, response, 200)
+
+ def _mock_cell_capacity(self):
+ self.mox.StubOutWithMock(self.cells.manager.state_manager,
+ 'get_our_capacities')
+ response = {"ram_free":
+ {"units_by_mb": {"8192": 0, "512": 13,
+ "4096": 1, "2048": 3, "16384": 0},
+ "total_mb": 7680},
+ "disk_free":
+ {"units_by_mb": {"81920": 11, "20480": 46,
+ "40960": 23, "163840": 5, "0": 0},
+ "total_mb": 1052672}
+ }
+ self.cells.manager.state_manager.get_our_capacities(). \
+ AndReturn(response)
+ self.mox.ReplayAll()
+
+
+class CellsCapacitySampleXmlTest(CellsCapacitySampleJsonTest):
+ ctype = 'xml'
+
+
class BareMetalNodesJsonTest(ApiSampleTestBase, bm_db_base.BMDBTestCase):
extension_name = ('nova.api.openstack.compute.contrib.baremetal_nodes.'
'Baremetal_nodes')