tricircle/tricircle/tests/unit/api/controllers/test_routing.py

396 lines
16 KiB
Python

# 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.
import mock
from mock import patch
from oslo_utils import uuidutils
import six
import unittest
import pecan
from tricircle.api.controllers import pod
from tricircle.api.controllers import routing
from tricircle.common import context
from tricircle.common import policy
from tricircle.db import api as db_api
from tricircle.db import core
class FakeResponse(object):
def __new__(cls, code=500):
cls.status = code
cls.status_code = code
return super(FakeResponse, cls).__new__(cls)
class RoutingControllerTest(unittest.TestCase):
def setUp(self):
core.initialize()
core.ModelBase.metadata.create_all(core.get_engine())
self.controller = routing.RoutingController()
self.context = context.get_admin_context()
policy.populate_default_rules()
def _validate_error_code(self, res, code):
self.assertEqual(res[list(res.keys())[0]]['code'], code)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(context, 'extract_context_from_environ')
def test_post(self, mock_context):
mock_context.return_value = self.context
# prepare the foreign key: pod_id
kw_pod = {'pod': {'region_name': 'pod1', 'az_name': 'az1'}}
pod_id = pod.PodsController().post(**kw_pod)['pod']['pod_id']
# a variable used for later test
project_id = uuidutils.generate_uuid()
kw_routing = {'routing':
{'top_id': '09fd7cc9-d169-4b5a-88e8-436ecf4d0bfe',
'bottom_id': 'dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef',
'pod_id': pod_id,
'project_id': project_id,
'resource_type': 'subnet'
}}
id = self.controller.post(**kw_routing)['routing']['id']
routing = db_api.get_resource_routing(self.context, id)
self.assertEqual('09fd7cc9-d169-4b5a-88e8-436ecf4d0bfe',
routing['top_id'])
self.assertEqual('dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef',
routing['bottom_id'])
self.assertEqual(pod_id, routing['pod_id'])
self.assertEqual(project_id, routing['project_id'])
self.assertEqual('subnet', routing['resource_type'])
routings = db_api.list_resource_routings(self.context,
[{'key': 'top_id',
'comparator': 'eq',
'value':
'09fd7cc9-d169-4b5a-'
'88e8-436ecf4d0bfe'
},
{'key': 'pod_id',
'comparator': 'eq',
'value': pod_id}
], [])
self.assertEqual(1, len(routings))
# failure case, only admin can create resource routing
self.context.is_admin = False
res = self.controller.post(**kw_routing)
self._validate_error_code(res, 403)
self.context.is_admin = True
# failure case, request body not found
kw_routing1 = {'route':
{'top_id': '109fd7cc9-d169-4b5a-88e8-436ecf4d0bfe',
'bottom_id': '2dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef',
'pod_id': pod_id,
'project_id': project_id,
'resource_type': 'subnet'
}}
res = self.controller.post(**kw_routing1)
self._validate_error_code(res, 400)
# failure case, top_id is not given
kw_routing2 = {'routing':
{'bottom_id': '2dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef',
'pod_id': pod_id,
'project_id': project_id,
'resource_type': 'subnet'
}}
res = self.controller.post(**kw_routing2)
self._validate_error_code(res, 400)
# failure case, top_id is empty
kw_routing3 = {'routing':
{'top_id': '',
'bottom_id': '2dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef',
'pod_id': pod_id,
'project_id': project_id,
'resource_type': 'subnet'
}}
res = self.controller.post(**kw_routing3)
self._validate_error_code(res, 400)
# failure case, top_id is given value 'None'
kw_routing4 = {'routing':
{'top_id': None,
'bottom_id': '2dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef',
'pod_id': pod_id,
'project_id': project_id,
'resource_type': 'subnet'
}}
res = self.controller.post(**kw_routing4)
self._validate_error_code(res, 400)
# failure case, wrong resource type
kw_routing6 = {'routing':
{'top_id': '09fd7cc9-d169-4b5a-88e8-436ecf4d0b09',
'bottom_id': 'dc80f9de-abb7-4ec6-ab7a-94f8fd1e2031f',
'pod_id': pod_id,
'project_id': project_id,
'resource_type': 'server'
}}
res = self.controller.post(**kw_routing6)
self._validate_error_code(res, 400)
# failure case, the resource routing already exists
res = self.controller.post(**kw_routing)
self._validate_error_code(res, 409)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(context, 'extract_context_from_environ')
def test_get_one(self, mock_context):
mock_context.return_value = self.context
# prepare the foreign key: pod_id
kw_pod = {'pod': {'region_name': 'pod1', 'az_name': 'az1'}}
pod_id = pod.PodsController().post(**kw_pod)['pod']['pod_id']
# a variable used for later test
project_id = uuidutils.generate_uuid()
kw_routing = {'routing':
{'top_id': '09fd7cc9-d169-4b5a-88e8-436ecf4d0bfe',
'bottom_id': 'dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef',
'pod_id': pod_id,
'project_id': project_id,
'resource_type': 'port'
}}
id = self.controller.post(**kw_routing)['routing']['id']
routing = self.controller.get_one(id)
self.assertEqual('09fd7cc9-d169-4b5a-88e8-436ecf4d0bfe',
routing['routing']['top_id'])
self.assertEqual('dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef',
routing['routing']['bottom_id'])
self.assertEqual(pod_id, routing['routing']['pod_id'])
self.assertEqual(project_id, routing['routing']['project_id'])
self.assertEqual('port', routing['routing']['resource_type'])
# failure case, only admin can get resource routing
self.context.is_admin = False
res = self.controller.get_one(id)
self._validate_error_code(res, 403)
self.context.is_admin = True
# failure case, resource routing not found
res = self.controller.get_one(-123)
self._validate_error_code(res, 404)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(context, 'extract_context_from_environ')
def test_get_all(self, mock_context):
mock_context.return_value = self.context
# prepare the foreign key: pod_id
kw_pod1 = {'pod': {'region_name': 'pod1', 'az_name': 'az1'}}
pod_id1 = pod.PodsController().post(**kw_pod1)['pod']['pod_id']
# a variable used for later test
project_id = uuidutils.generate_uuid()
kw_routing1 = {'routing':
{'top_id': 'c7f641c9-8462-4007-84b2-3035d8cfb7a3',
'bottom_id': 'dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef',
'pod_id': pod_id1,
'project_id': project_id,
'resource_type': 'subnet'
}}
# prepare the foreign key: pod_id
kw_pod2 = {'pod': {'region_name': 'pod2', 'az_name': 'az1'}}
pod_id2 = pod.PodsController().post(**kw_pod2)['pod']['pod_id']
kw_routing2 = {'routing':
{'top_id': 'b669a2da-ca95-47db-a2a9-ba9e546d82ee',
'bottom_id': 'fd72c010-6e62-4866-b999-6dcb718dd7b4',
'pod_id': pod_id2,
'project_id': project_id,
'resource_type': 'port'
}}
self.controller.post(**kw_routing1)
self.controller.post(**kw_routing2)
# no filters are applied to the routings, so all of the routings will
# be retrieved.
routings = self.controller.get_all()
actual = [(routing['top_id'], routing['pod_id'])
for routing in routings['routings']]
expect = [('c7f641c9-8462-4007-84b2-3035d8cfb7a3', pod_id1),
('b669a2da-ca95-47db-a2a9-ba9e546d82ee', pod_id2)]
six.assertCountEqual(self, expect, actual)
# apply a resource type filter to the retrieved routings.
kw_filter1 = {'resource_type': 'port'}
routings = self.controller.get_all(**kw_filter1)
actual = [(routing['top_id'], routing['pod_id'],
routing['resource_type'])
for routing in routings['routings']]
expect = [('b669a2da-ca95-47db-a2a9-ba9e546d82ee', pod_id2, 'port')]
six.assertCountEqual(self, expect, actual)
# apply a filter and if it doesn't match with any of the retrieved
# routings, then all of them will be discarded and the method returns
# with []
kw_filter2 = {'resource_type': 'port2'}
routings = self.controller.get_all(**kw_filter2)
self.assertEqual([], routings['routings'])
# apply an illegal filter and it won't take effect
kw_filter3 = {'resource': 'port'}
routings = self.controller.get_all(**kw_filter3)
actual = [(routing['top_id'], routing['pod_id'])
for routing in routings['routings']]
expect = [('c7f641c9-8462-4007-84b2-3035d8cfb7a3', pod_id1),
('b669a2da-ca95-47db-a2a9-ba9e546d82ee', pod_id2)]
six.assertCountEqual(self, expect, actual)
# failure case, only admin can show all resource routings
self.context.is_admin = False
res = self.controller.get_all()
self._validate_error_code(res, 403)
self.context.is_admin = True
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(pecan, 'response', new=mock.Mock)
@patch.object(context, 'extract_context_from_environ')
def test_delete(self, mock_context):
mock_context.return_value = self.context
# prepare the foreign key: pod_id
kw_pod = {'pod': {'region_name': 'pod1', 'az_name': 'az1'}}
pod_id = pod.PodsController().post(**kw_pod)['pod']['pod_id']
# a variable used for later test
project_id = uuidutils.generate_uuid()
kw_routing = {'routing':
{'top_id': '09fd7cc9-d169-4b5a-88e8-436ecf4d0bfe',
'bottom_id': 'dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef',
'pod_id': pod_id,
'project_id': project_id,
'resource_type': 'subnet'
}}
routing = self.controller.post(**kw_routing)
id = routing['routing']['id']
res = self.controller.delete(id)
self.assertEqual(200, res.status)
routings = db_api.list_resource_routings(self.context,
[{'key': 'top_id',
'comparator': 'eq',
'value': '09fd7cc9-d'
'169-4b5a-88e8-436ecf4d0bfe'
},
{'key': 'pod_id',
'comparator': 'eq',
'value': pod_id
}], [])
self.assertEqual(0, len(routings))
# failure case, only admin can delete resource routing
self.context.is_admin = False
res = self.controller.delete(id)
self._validate_error_code(res, 403)
self.context.is_admin = True
# failure case, resource routing not found
res = self.controller.delete(-123)
self._validate_error_code(res, 404)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(pecan, 'response', new=mock.Mock)
@patch.object(context, 'extract_context_from_environ')
def test_put(self, mock_context):
mock_context.return_value = self.context
# prepare the foreign key: pod_id
kw_pod1 = {'pod': {'region_name': 'pod1', 'az_name': 'az1'}}
pod_id1 = pod.PodsController().post(**kw_pod1)['pod']['pod_id']
# a variable used for later test
project_id = uuidutils.generate_uuid()
body = {'routing':
{'top_id': 'c7f641c9-8462-4007-84b2-3035d8cfb7a3',
'bottom_id': 'dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef',
'pod_id': pod_id1,
'project_id': project_id,
'resource_type': 'router'
}}
# both bottom_id and resource type have been changed
body_update1 = {'routing':
{'bottom_id': 'fd72c010-6e62-4866-b999-6dcb718dd7b4',
'resource_type': 'port'
}}
id = self.controller.post(**body)['routing']['id']
routing = self.controller.put(id, **body_update1)
self.assertEqual('port',
routing['routing']['resource_type'])
self.assertEqual('fd72c010-6e62-4866-b999-6dcb718dd7b4',
routing['routing']['bottom_id'])
self.assertEqual(pod_id1, routing['routing']['pod_id'])
# failure case, only admin can update resource routing
self.context.is_admin = False
res = self.controller.put(id, **body_update1)
self._validate_error_code(res, 403)
self.context.is_admin = True
# failure case, request body not found
body_update2 = {'route':
{'bottom_id': 'fd72c010-6e62-4866-b999-6dcb718dd7b4',
'resource_type': 'port'
}}
res = self.controller.put(id, **body_update2)
self._validate_error_code(res, 400)
# failure case, wrong resource type
body_update3 = {'routing':
{'resource_type': 'volume'}}
res = self.controller.put(id, **body_update3)
self._validate_error_code(res, 400)
# failure case, the value to be updated is empty
body_update4 = {'routing':
{'top_id': ''}}
res = self.controller.put(id, **body_update4)
self._validate_error_code(res, 400)
# failure case, the value to be updated is None
body_update5 = {'routing':
{'top_id': None}}
res = self.controller.put(id, **body_update5)
self._validate_error_code(res, 400)
# failure case, the value to be updated is not appropriate
res = self.controller.put(-123, **body_update1)
self._validate_error_code(res, 404)
def tearDown(self):
core.ModelBase.metadata.drop_all(core.get_engine())