From c4f96afbcce1a4d667546034c169c0a88711391f Mon Sep 17 00:00:00 2001 From: Davanum Srinivas Date: Thu, 4 Dec 2014 15:22:52 -0500 Subject: [PATCH] Fix REST API and test case for Containers Change-Id: I4506dc2e7810940ae2972c4307f1335217ca5f9d --- magnum/api/controllers/v1/container.py | 34 +++++------ magnum/db/sqlalchemy/models.py | 1 + magnum/objects/container.py | 1 + magnum/tests/test_functional.py | 83 ++++++++++++-------------- 4 files changed, 56 insertions(+), 63 deletions(-) diff --git a/magnum/api/controllers/v1/container.py b/magnum/api/controllers/v1/container.py index ce6c976cbd..959c19c81f 100644 --- a/magnum/api/controllers/v1/container.py +++ b/magnum/api/controllers/v1/container.py @@ -41,8 +41,8 @@ class Container(base.APIBase): """API representation of a container. This class enforces type checking and value constraints, and converts - between the internal object model and the API representation - of a container. + between the internal object model and the API representation of a + container. """ _container_uuid = None @@ -61,7 +61,7 @@ class Container(base.APIBase): # NOTE(lucasagomes): Create the container_id attribute # on-the-fly to satisfy the api -> rpc object conversion. self.container_id = container.id - except exception.BayNotFound as e: + except exception.ContainerNotFound as e: # Change error code because 404 (NotFound) is inappropriate # response for a POST request to create a Container e.code = 400 # BadRequest @@ -75,9 +75,6 @@ class Container(base.APIBase): name = wtypes.text """Name of this container""" - type = wtypes.text - """Type of this container""" - links = wsme.wsattr([link.Link], readonly=True) """A list containing a self link and associated container links""" @@ -105,7 +102,7 @@ class Container(base.APIBase): @staticmethod def _convert_with_links(container, url, expand=True): if not expand: - container.unset_fields_except(['uuid']) + container.unset_fields_except(['uuid', 'name']) # never expose the container_id attribute container.container_id = wtypes.Unset @@ -128,7 +125,6 @@ class Container(base.APIBase): def sample(cls, expand=True): sample = cls(uuid='27e3153e-d5bf-4b7e-b517-fb518e17f34c', name='example', - type='virt', created_at=datetime.datetime.utcnow(), updated_at=datetime.datetime.utcnow()) # NOTE(lucasagomes): container_uuid getter() method look at the @@ -147,8 +143,8 @@ class ContainerCollection(collection.Collection): self._type = 'containers' @staticmethod - def convert_with_links(rpc_containers, limit, url=None, expand=False, - **kwargs): + def convert_with_links(rpc_containers, limit, url=None, + expand=False, **kwargs): collection = ContainerCollection() collection.containers = [Container.convert_with_links(p, expand) for p in rpc_containers] @@ -167,7 +163,7 @@ class ContainersController(rest.RestController): from_containers = False """A flag to indicate if the requests to this controller are coming - from the top-level resource Nodes.""" + from the top-level resource Containers.""" _custom_actions = { 'detail': ['GET'], @@ -301,14 +297,18 @@ class ContainersController(rest.RestController): if rpc_container[field] != patch_val: rpc_container[field] = patch_val - rpc_container = objects.Container.get_by_id(pecan.request.context, - rpc_container.container_id) - topic = pecan.request.rpcapi.get_topic_for(rpc_container) + if hasattr(pecan.request, 'rpcapi'): + rpc_container = objects.Container.get_by_id(pecan.request.context, + rpc_container.container_id) + topic = pecan.request.rpcapi.get_topic_for(rpc_container) - new_container = pecan.request.rpcapi.update_container( - pecan.request.context, rpc_container, topic) + new_container = pecan.request.rpcapi.update_container( + pecan.request.context, rpc_container, topic) - return Container.convert_with_links(new_container) + return Container.convert_with_links(new_container) + else: + rpc_container.save() + return Container.convert_with_links(rpc_container) @wsme_pecan.wsexpose(None, types.uuid, status_code=204) def delete(self, container_uuid): diff --git a/magnum/db/sqlalchemy/models.py b/magnum/db/sqlalchemy/models.py index cb356d5ff2..05a6c299fe 100644 --- a/magnum/db/sqlalchemy/models.py +++ b/magnum/db/sqlalchemy/models.py @@ -135,6 +135,7 @@ class Container(Base): ) id = Column(Integer, primary_key=True) uuid = Column(String(36)) + name = Column(String(255)) class Pod(Base): diff --git a/magnum/objects/container.py b/magnum/objects/container.py index 1e2d68008b..2f715760a2 100644 --- a/magnum/objects/container.py +++ b/magnum/objects/container.py @@ -34,6 +34,7 @@ class Container(base.MagnumObject): fields = { 'id': int, 'uuid': obj_utils.str_or_none, + 'name': obj_utils.str_or_none, } @staticmethod diff --git a/magnum/tests/test_functional.py b/magnum/tests/test_functional.py index 07822ee013..80716494e7 100644 --- a/magnum/tests/test_functional.py +++ b/magnum/tests/test_functional.py @@ -148,49 +148,40 @@ class TestPodController(db_base.DbTestCase): self.assertEqual(0, len(c)) -# class TestContainerController(tests.FunctionalTest): -# def test_container_api(self): -# # Create a container -# params = '{"desc": "My Docker Containers", "name": "My Docker"}' -# response = self.app.post('/v1/containers', -# params=params, -# content_type='application/json') -# self.assertEqual(response.status_int, 200) -# -# # Get all containers -# response = self.app.get('/v1/containers') -# self.assertEqual(response.status_int, 200) -# self.assertEqual(1, len(response.json)) -# c = response.json[0] -# self.assertIsNotNone(c.get('uuid')) -# self.assertEqual('My Docker', c.get('name')) -# self.assertEqual('My Docker Containers', c.get('desc')) -# -# # Get just the one we created -# response = self.app.get('/v1/containers/%s' % c.get('uuid')) -# self.assertEqual(response.status_int, 200) -# -# # Update the description -# params = ('{"uuid":"' + c.get('uuid') + '", ' -# '"desc": "My Docker Containers - 2", ' -# '"name": "My Docker"}') -# response = self.app.put('/v1/containers', -# params=params, -# content_type='application/json') -# self.assertEqual(response.status_int, 200) -# -# # Execute some actions -# actions = ['start', 'stop', 'pause', 'unpause', -# 'reboot', 'logs', 'execute'] -# for action in actions: -# response = self.app.put('/v1/containers/%s/%s' % (c.get('uuid'), -# action)) -# self.assertEqual(response.status_int, 200) -# -# # Delete the container we created -# response = self.app.delete('/v1/containers/%s' % c.get('uuid')) -# self.assertEqual(response.status_int, 200) -# -# response = self.app.get('/v1/containers') -# self.assertEqual(response.status_int, 200) -# self.assertEqual(0, len(response.json)) +class TestContainerController(db_base.DbTestCase): + def test_containers_api(self): + # Create a container + params = '{"name": "My Docker"}' + response = self.app.post('/v1/containers', + params=params, + content_type='application/json') + self.assertEqual(response.status_int, 201) + + # Get all containers + response = self.app.get('/v1/containers') + self.assertEqual(response.status_int, 200) + self.assertEqual(1, len(response.json)) + c = response.json['containers'][0] + self.assertIsNotNone(c.get('uuid')) + self.assertEqual('My Docker', c.get('name')) + + # Get just the one we created + response = self.app.get('/v1/containers/%s' % c.get('uuid')) + self.assertEqual(response.status_int, 200) + + # Update the description + params = [{'path': '/name', + 'value': 'container_example_B', + 'op': 'replace'}] + response = self.app.patch_json('/v1/containers/%s' % c.get('uuid'), + params=params) + self.assertEqual(response.status_int, 200) + + # Delete the bay we created + response = self.app.delete('/v1/containers/%s' % c.get('uuid')) + self.assertEqual(response.status_int, 204) + + response = self.app.get('/v1/containers') + self.assertEqual(response.status_int, 200) + c = response.json['containers'] + self.assertEqual(0, len(c))