ooi/ooi/tests/functional/middleware/test_network_controller.py

465 lines
19 KiB
Python

# Copyright 2015 Spanish National Research Council
# Copyright 2015 LIP - INDIGO-DataCloud
#
# 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
import uuid
import warnings
from oslo_config import cfg
import webob
from ooi.api import helpers
from ooi.tests import fakes_network as fakes
from ooi.tests.functional.middleware import test_middleware
from ooi import utils
from ooi import wsgi
class TestNetNeutronController(test_middleware.TestMiddleware):
"""Test OCCI network controller."""
def setUp(self):
super(TestNetNeutronController, self).setUp()
self.schema = 'http://schemas.ogf.org/occi/infrastructure#network'
self.accept = self.content_type = None
self.application_url = fakes.application_url
neutron_ooi_endpoint = "foo"
def mock_endpoint(self, bar):
if bar == "neutron_ooi_endpoint":
return neutron_ooi_endpoint
with mock.patch.object(cfg.ConfigOpts, "__getattr__",
side_effect=mock_endpoint,
autospec=True):
self.app = wsgi.OCCIMiddleware(None)
def assertExpectedResult(self, expected, result):
expected = ["%s: %s" % e for e in expected]
# NOTE(aloga): the order of the result does not matter
results = str(result.text).splitlines()
self.assertItemsEqual(expected, results)
def test_deprecated_configuration(self):
with warnings.catch_warnings(record=True) as w:
neutron_endopoint = "/foo"
warnings.simplefilter("always", DeprecationWarning)
wsgi.OCCIMiddleware(None,
neutron_ooi_endpoint=neutron_endopoint)
expected_message = (
"Configuration of neutron_ooi_endpoint"
" in api-paste.ini file is deprecated,"
" include it in nova.conf")
self.assertEqual(1, len(w))
self.assertIs(DeprecationWarning,
w[-1].category)
self.assertEqual(expected_message, w[-1].message.message)
@mock.patch.object(helpers.BaseHelper, "_get_req")
def test_list_networks_empty(self, m):
tenant = fakes.tenants["bar"]
out = fakes.create_fake_json_resp(
{"networks": fakes.networks[tenant['id']]}, 200)
m.return_value.get_response.return_value = out
req = self._build_req(path="/network",
tenant_id='X', method="GET")
resp = req.get_response(self.app)
self.assertEqual(204, resp.status_code)
expected_result = ""
self.assertExpectedResult(expected_result, resp)
self.assertDefaults(resp)
@mock.patch.object(helpers.BaseHelper, "_get_req")
def test_list_networks(self, m):
tenant = fakes.tenants["foo"]
out = fakes.create_fake_json_resp(
{"networks": fakes.networks[tenant['id']]}, 200)
m.return_value.get_response.return_value = out
req = self._build_req(path="/network",
tenant_id='X', method="GET")
resp = req.get_response(self.app)
self.assertEqual(200, resp.status_code)
expected = []
for s in fakes.networks[tenant["id"]]:
expected.append(
("X-OCCI-Location",
utils.join_url(self.application_url + "/",
"network/%s" % s["id"]))
)
self.assertDefaults(resp)
self.assertExpectedResult(expected, resp)
@mock.patch.object(helpers.BaseHelper, "_get_req")
def test_create(self, m):
tenant = fakes.tenants["foo"]
net_out = fakes.create_fake_json_resp(
{"network": fakes.networks[tenant['id']][0]}, 200)
mock_net = mock.Mock(webob.Request)
mock_net.get_response.return_value = net_out
subnet_out = fakes.create_fake_json_resp(
{"subnet": fakes.networks[tenant['id']][0]["subnet_info"]},
200)
mock_subnet = mock.Mock(webob.Request)
mock_subnet.get_response.return_value = subnet_out
list_router_out = fakes.create_fake_json_resp(
{"routers": []},
200)
mock_list_router = mock.Mock(webob.Request)
mock_list_router.get_response.return_value = list_router_out
public_out = fakes.create_fake_json_resp(
{"networks": fakes.networks[tenant['id']]},
200)
mock_public = mock.Mock(webob.Request)
mock_public.get_response.return_value = public_out
router_out = fakes.create_fake_json_resp(
{"router": {"id": uuid.uuid4().hex}},
200)
mock_router = mock.Mock(webob.Request)
mock_router.get_response.return_value = router_out
mock_iface = mock.Mock(webob.Request)
mock_iface.get_response.return_value = fakes.create_fake_json_resp(
{"foo": "foo"}, 200)
m.side_effect = [mock_net, mock_subnet, mock_list_router, mock_public,
mock_router, mock_iface
]
name = fakes.networks[tenant["id"]][0]["name"]
net_id = fakes.networks[tenant["id"]][0]["id"]
address = fakes.networks[tenant["id"]][0]["subnet_info"]["cidr"]
headers = {
'Category': 'network;'
' scheme='
'"http://schemas.ogf.org/occi/infrastructure#";'
'class="kind",'
'ipnetwork;'
' scheme='
'"http://schemas.ogf.org/occi/infrastructure/'
'network#";'
'class="mixin",',
'X-OCCI-Attribute': 'occi.core.title="%s",'
'occi.network.address="%s"' %
(name, address)
}
req = self._build_req(path="/network",
tenant_id='X',
method="POST",
headers=headers)
m.return_value = fakes.networks[tenant['id']][0]
resp = req.get_response(self.app)
self.assertEqual(200, resp.status_code)
expected = [("X-OCCI-Location",
utils.join_url(self.application_url + "/",
"network/%s" % net_id))]
self.assertExpectedResult(expected, resp)
@mock.patch.object(helpers.BaseHelper, "_get_req")
def test_create_router_exists(self, m):
tenant = fakes.tenants["foo"]
net_out = fakes.create_fake_json_resp(
{"network": fakes.networks[tenant['id']][0]}, 200)
mock_net = mock.Mock(webob.Request)
mock_net.get_response.return_value = net_out
subnet_out = fakes.create_fake_json_resp(
{"subnet": fakes.networks[tenant['id']][0]["subnet_info"]},
200)
mock_subnet = mock.Mock(webob.Request)
mock_subnet.get_response.return_value = subnet_out
list_router_out = fakes.create_fake_json_resp(
{"routers": [
{"id": uuid.uuid4().hex,
"external_gateway_info": None},
{"id": uuid.uuid4().hex,
"external_gateway_info": {"network_id": uuid.uuid4().hex}},
]
},
200)
mock_list_router = mock.Mock(webob.Request)
mock_list_router.get_response.return_value = list_router_out
public_out = fakes.create_fake_json_resp(
{"networks": fakes.networks[tenant['id']]},
200)
mock_public = mock.Mock(webob.Request)
mock_public.get_response.return_value = public_out
router_out = fakes.create_fake_json_resp(
{"router": {"id": uuid.uuid4().hex}},
200)
mock_router = mock.Mock(webob.Request)
mock_router.get_response.return_value = router_out
mock_iface = mock.Mock(webob.Request)
mock_iface.get_response.return_value = fakes.create_fake_json_resp(
{"foo": "foo"}, 200)
m.side_effect = [mock_net, mock_subnet, mock_list_router, mock_public,
mock_router, mock_iface
]
name = fakes.networks[tenant["id"]][0]["name"]
net_id = fakes.networks[tenant["id"]][0]["id"]
address = fakes.networks[tenant["id"]][0]["subnet_info"]["cidr"]
headers = {
'Category': 'network;'
' scheme='
'"http://schemas.ogf.org/occi/infrastructure#";'
'class="kind",'
'ipnetwork;'
' scheme='
'"http://schemas.ogf.org/occi/infrastructure/'
'network#";'
'class="mixin",',
'X-OCCI-Attribute': 'occi.core.title="%s",'
'occi.network.address="%s"' %
(name, address)
}
req = self._build_req(path="/network",
tenant_id='X',
method="POST",
headers=headers)
m.return_value = fakes.networks[tenant['id']][0]
resp = req.get_response(self.app)
self.assertEqual(200, resp.status_code)
expected = [("X-OCCI-Location",
utils.join_url(self.application_url + "/",
"network/%s" % net_id))]
self.assertExpectedResult(expected, resp)
@mock.patch.object(helpers.BaseHelper, "_get_req")
def test_show_networks(self, m):
tenant = fakes.tenants["foo"]
for n in fakes.networks[tenant["id"]]:
net_out = fakes.create_fake_json_resp(
{"network": n}, 200)
mock_net = mock.Mock(webob.Request)
mock_net.get_response.return_value = net_out
subnet_out = fakes.create_fake_json_resp(
{"subnet": n["subnet_info"]}, 200)
mock_subnet = mock.Mock(webob.Request)
mock_subnet.get_response.return_value = subnet_out
m.side_effect = [mock_net, mock_subnet]
req = self._build_req(path="/network/%s" % n["id"],
tenant_id='X',
method="GET")
resp = req.get_response(self.app)
expected = fakes.build_occi_network(n)
self.assertEqual(200, resp.status_code)
self.assertDefaults(resp)
self.assertExpectedResult(expected, resp)
@mock.patch.object(helpers.BaseHelper, "_get_req")
def test_delete_networks(self, m):
tenant = fakes.tenants["foo"]
port_out = fakes.create_fake_json_resp(
{"ports": fakes.ports[tenant['id']]}, 200)
mock_port = mock.Mock(webob.Request)
mock_port.get_response.return_value = port_out
empty_out = fakes.create_fake_json_resp([], 204)
mock_empty = mock.Mock(webob.Request)
mock_empty.get_response.return_value = empty_out
m.side_effect = [mock_port, mock_empty, mock_empty,
mock_empty, mock_empty]
for n in fakes.networks[tenant["id"]]:
m.return_value = fakes.create_fake_json_resp(
{"subnet": n["subnet_info"]}, 200)
req = self._build_req(path="/network/%s" % n["id"],
tenant_id='X',
method="DELETE")
resp = req.get_response(self.app)
self.assertEqual(204, resp.status_code)
self.assertDefaults(resp)
class NetworkNeutronTextPlain(test_middleware.TestMiddlewareTextPlain,
TestNetNeutronController):
"""Test OCCI network controller with Accept: text/plain."""
class NetworklNeutronTextOcci(test_middleware.TestMiddlewareTextOcci,
TestNetNeutronController):
"""Test OCCI network controller with Accept: text/occi."""
class TestNetNovaController(test_middleware.TestMiddleware):
"""Test OCCI network controller."""
def setUp(self):
super(TestNetNovaController, self).setUp()
self.schema = 'http://schemas.ogf.org/occi/infrastructure#network'
self.accept = self.content_type = None
self.application_url = fakes.application_url
self.app = wsgi.OCCIMiddleware(None)
def assertExpectedResult(self, expected, result):
expected = ["%s: %s" % e for e in expected]
# NOTE(aloga): the order of the result does not matter
results = str(result.text).splitlines()
self.assertItemsEqual(expected, results)
@mock.patch.object(helpers.BaseHelper, "_get_req")
def test_list_networks_empty(self, m):
tenant = fakes.tenants["bar"]
out = fakes.create_fake_json_resp(
{"networks": fakes.networks_nova[tenant['id']]}, 200)
m.return_value.get_response.return_value = out
req = self._build_req(path="/network",
tenant_id='X', method="GET")
resp = req.get_response(self.app)
self.assertEqual(204, resp.status_code)
expected_result = ""
self.assertExpectedResult(expected_result, resp)
self.assertDefaults(resp)
@mock.patch.object(helpers.BaseHelper, "_get_req")
def test_list_networks(self, m):
tenant = fakes.tenants["foo"]
out = fakes.create_fake_json_resp(
{"networks": fakes.networks_nova[tenant['id']]}, 200)
m.return_value.get_response.return_value = out
req = self._build_req(path="/network",
tenant_id='X', method="GET")
resp = req.get_response(self.app)
self.assertEqual(200, resp.status_code)
expected = []
for s in fakes.networks_nova[tenant["id"]]:
expected.append(
("X-OCCI-Location",
utils.join_url(self.application_url + "/",
"network/%s" % s["id"]))
)
self.assertDefaults(resp)
self.assertExpectedResult(expected, resp)
@mock.patch.object(helpers.BaseHelper, "_get_req")
def test_create(self, m):
tenant = fakes.tenants["foo"]
net_out = fakes.create_fake_json_resp(
{"network": fakes.networks_nova[tenant['id']][0]}, 200)
mock_net = mock.Mock(webob.Request)
mock_net.get_response.return_value = net_out
m.side_effect = [mock_net]
name = fakes.networks_nova[tenant["id"]][0]["label"]
net_id = fakes.networks_nova[tenant["id"]][0]["id"]
address = fakes.networks_nova[tenant["id"]][0]["cidr"]
headers = {
'Category': 'network;'
' scheme='
'"http://schemas.ogf.org/occi/infrastructure#";'
'class="kind",'
'ipnetwork;'
' scheme='
'"http://schemas.ogf.org/occi/'
'infrastructure/network#";'
'class="mixin",',
'X-OCCI-Attribute': 'occi.core.title="%s",'
'occi.network.address="%s"' %
(name, address)
}
req = self._build_req(path="/network",
tenant_id='X',
method="POST",
headers=headers)
m.return_value = fakes.networks_nova[tenant['id']][0]
resp = req.get_response(self.app)
self.assertEqual(200, resp.status_code)
expected = [("X-OCCI-Location",
utils.join_url(self.application_url + "/",
"network/%s" % net_id))]
self.assertExpectedResult(expected, resp)
@mock.patch.object(helpers.BaseHelper, "_get_req")
def test_show_networks(self, m):
tenant = fakes.tenants["foo"]
for n in fakes.networks_nova[tenant["id"]]:
net_out = fakes.create_fake_json_resp(
{"network": n}, 200)
mock_net = mock.Mock(webob.Request)
mock_net.get_response.return_value = net_out
m.side_effect = [mock_net]
req = self._build_req(path="/network/%s" % n["id"],
tenant_id='X',
method="GET")
resp = req.get_response(self.app)
expected = fakes.build_occi_nova(n)
self.assertEqual(200, resp.status_code)
self.assertDefaults(resp)
self.assertExpectedResult(expected, resp)
@mock.patch.object(helpers.BaseHelper, "_get_req")
def test_delete_networks(self, m):
tenant = fakes.tenants["foo"]
empty_out = fakes.create_fake_json_resp(
[], 204)
mock_empty = mock.Mock(webob.Request)
mock_empty.get_response.return_value = empty_out
for n in fakes.networks_nova[tenant["id"]]:
m.side_effect = [mock_empty]
req = self._build_req(path="/network/%s" % n["id"],
tenant_id='X',
method="DELETE")
resp = req.get_response(self.app)
self.assertEqual(204, resp.status_code)
self.assertDefaults(resp)
def test_action_net(self):
tenant = fakes.tenants["foo"]
for action in ("up", "down"):
headers = {
'Category': (
'%s;'
'scheme="http://schemas.ogf.org/occi/infrastructure/'
'network/action#";'
'class="action"' % action)
}
for net in fakes.networks[tenant["id"]]:
req = self._build_req("/network/%s?action=%s" % (net["id"],
action),
tenant_id=tenant["id"], method="POST",
headers=headers)
resp = req.get_response(self.app)
self.assertDefaults(resp)
self.assertEqual(501, resp.status_code)
def test_invalid_action(self):
tenant = fakes.tenants["foo"]
action = "foo"
for net in fakes.networks[tenant["id"]]:
req = self._build_req("/network/%s?action=%s" % (net["id"],
action),
tenant["id"], method="POST")
resp = req.get_response(self.app)
self.assertDefaults(resp)
self.assertEqual(400, resp.status_code)
class NetworkNovaControllerTextPlain(test_middleware.TestMiddlewareTextPlain,
TestNetNovaController):
"""Test OCCI network controller with Accept: text/plain."""
class NetworkNovaControllerTextOcci(test_middleware.TestMiddlewareTextOcci,
TestNetNovaController):
"""Test OCCI network controller with Accept: text/occi."""