Increase attribute types

In order to do proper JSON rendering, ooi needs to to further refine
the Object attribute type into numbers, bools and strings. All
attributes are updated to include the type. Object attribute type is
only used now for source and targets in links. Handling of attributes
in network is simplified thanks to this change.

Change-Id: If1c0e6b1e08139b369b3c68c4a12ff7244c3445f
This commit is contained in:
Enol Fernandez
2016-11-09 22:53:33 +00:00
committed by Enol Fernández
parent 1df2897254
commit 967f1a2cab
18 changed files with 226 additions and 109 deletions

View File

@@ -15,6 +15,7 @@
import json
import uuid
import six
import webob.dec
import webob.exc
@@ -39,14 +40,14 @@ subnets = [
"id": uuid.uuid4().hex,
"name": "private-subnet",
"cidr": "33.0.0.1/24",
"ip_version": "IPv4",
"ip_version": 4,
"gateway_ip": "33.0.0.1",
},
{
"id": uuid.uuid4().hex,
"name": "public-subnet",
"cidr": "44.0.0.1/24",
"ip_version": "IPv4",
"ip_version": 4,
"gateway_ip": "44.0.0.1",
},
]
@@ -212,8 +213,10 @@ def create_header_occi(params, category, project=None):
att = ""
if params is not None:
for k, v in params.items():
# FIXME(enolfc): this assumes all attributes are strings
att = "%s, %s=\"%s\"" % (att, k, v)
if isinstance(v, six.string_types):
att = "%s, %s=\"%s\"" % (att, k, v)
else:
att = "%s, %s=%s" % (att, k, v)
headers["X_OCCI_Attribute"] = att
if category is not None:
cat = ""
@@ -249,7 +252,7 @@ def fake_network_link_occi(os_list_net):
def fake_build_net(name, ip_version=4, address='0.0.0.11', gateway='0.0.0.1',
id=33, state='active'):
id="33", state='active'):
link = {}
link['id'] = id
link['name'] = name
@@ -309,7 +312,7 @@ def build_occi_network(network):
'occi.core.id="%s"' % network_id,
'occi.core.title="%s"' % name,
'occi.network.state="%s"' % status,
'org.openstack.network.ip_version="%s"' % subnet_info["ip_version"],
'org.openstack.network.ip_version=%s' % subnet_info["ip_version"],
'occi.network.address="%s"' % subnet_info["cidr"],
'occi.network.gateway="%s"' % subnet_info["gateway_ip"],
]

View File

@@ -675,7 +675,7 @@ class TestOpenStackHelper(TestBaseHelper):
req_mock.get_response.return_value = resp
m.return_value = req_mock
name = uuid.uuid4().hex
size = "10"
size = 10
ret = self.helper.volume_create(None, name, size)
self.assertEqual("FOO", ret)
m.assert_called_with(None, name, size)
@@ -689,7 +689,7 @@ class TestOpenStackHelper(TestBaseHelper):
req_mock.get_response.return_value = resp
m.return_value = req_mock
name = uuid.uuid4().hex
size = "10"
size = 10
m_exc.return_value = webob.exc.HTTPInternalServerError()
self.assertRaises(webob.exc.HTTPInternalServerError,
self.helper.volume_create,
@@ -1081,7 +1081,7 @@ class TestOpenStackHelperReqs(TestBaseHelper):
tenant = fakes.tenants["foo"]
req = self._build_req(tenant["id"])
name = "foo server"
size = "10"
size = 10
body = {
"volume": {

View File

@@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import collections
import uuid
import mock
@@ -50,6 +51,7 @@ class TestNetworkControllerNeutron(base.TestController):
@mock.patch.object(helpers_neutron.OpenStackNeutron, "get_network_details")
def test_show(self, m_network):
m_network.return_value = collections.defaultdict(lambda: "foo")
test_networks = fakes.networks[fakes.tenants["foo"]["id"]]
for net in test_networks:
ret = self.controller.show(None, net["id"])
@@ -133,7 +135,7 @@ class TestNetworkControllerNeutron(base.TestController):
def test_filter_attributes(self):
parameters = {"occi.core.title": 'name',
"org.openstack.network.ip_version": '4',
"org.openstack.network.ip_version": 4,
"occi.network.address": '00001/24',
"occi.network.gateway": '00001',
}
@@ -146,7 +148,6 @@ class TestNetworkControllerNeutron(base.TestController):
]
}
ret = network_api.process_parameters(req, occi_scheme)
self.assertIsNotNone(ret)
self.assertEqual(parameters, ret)
def test_filter_attributes_empty(self):
@@ -159,7 +160,7 @@ class TestNetworkControllerNeutron(base.TestController):
]
}
attributes = network_api.process_parameters(req, occi_scheme)
self.assertIsNone(attributes)
self.assertEqual({}, attributes)
def test_run_action_invalid(self):
tenant = fakes.tenants["foo"]
@@ -206,6 +207,7 @@ class TestNetworkControllerNova(base.TestController):
@mock.patch.object(helpers.OpenStackHelper, "get_network_details")
def test_show(self, m_network):
m_network.return_value = collections.defaultdict(lambda: "foo")
test_networks = fakes.networks[fakes.tenants["foo"]["id"]]
for net in test_networks:
ret = self.controller.show(None, net["id"])
@@ -305,4 +307,4 @@ class TestNetworkControllerNova(base.TestController):
self.controller.run_action,
req,
server_uuid,
None)
None)

View File

@@ -87,7 +87,7 @@ class TestStorageController(base.TestController):
tenant = fakes.tenants["foo"]
req = self._build_req(tenant["id"])
name = "foo volume"
size = "10"
size = 10
obj = {
"attributes": {
"occi.core.title": name,

View File

@@ -51,9 +51,11 @@ class TestAttributes(base.TestCase):
attr = attribute.MutableAttribute("occi.foo.bar", "bar")
attr.value = "bazonk"
self.assertEqual("bazonk", attr.value)
self.assertEqual(attribute.AttributeType.object_type, attr.attr_type)
def test_inmutable(self):
attr = attribute.InmutableAttribute("occi.foo.bar", "bar")
self.assertEqual(attribute.AttributeType.object_type, attr.attr_type)
def set_val():
attr.value = "bazonk"
@@ -61,32 +63,58 @@ class TestAttributes(base.TestCase):
self.assertRaises(AttributeError, set_val)
def test_attribute_type_list(self):
attr = attribute.MutableAttribute(
"occi.foo.bar", "bar", attr_type=attribute.AttributeType.list_type)
attr.value = ['2']
def set_object_val():
attr.value = "object"
def set_hash_val():
attr.value = {}
self.assertRaises(TypeError, set_object_val)
self.assertRaises(TypeError, set_hash_val)
l = attribute.AttributeType.list_type
l.check_type([1])
l.check_type(None)
self.assertRaises(TypeError, l.check_type, 1)
self.assertRaises(TypeError, l.check_type, {"a": "b"})
self.assertRaises(TypeError, l.check_type, "foo")
self.assertRaises(TypeError, l.check_type, True)
def test_attribute_type_hash(self):
attr = attribute.MutableAttribute(
"occi.foo.bar", "bar", attr_type=attribute.AttributeType.hash_type)
attr.value = {'foo': 'bar'}
h = attribute.AttributeType.hash_type
h.check_type({})
h.check_type(None)
self.assertRaises(TypeError, h.check_type, 1)
self.assertRaises(TypeError, h.check_type, [])
self.assertRaises(TypeError, h.check_type, "foo")
self.assertRaises(TypeError, h.check_type, True)
def set_object_val():
attr.value = "object"
def test_attribute_type_string(self):
s = attribute.AttributeType.string_type
s.check_type("hey")
s.check_type(None)
self.assertRaises(TypeError, s.check_type, 1)
self.assertRaises(TypeError, s.check_type, [])
self.assertRaises(TypeError, s.check_type, {})
self.assertRaises(TypeError, s.check_type, True)
def set_list_val():
attr.value = []
def test_attribute_type_number(self):
n = attribute.AttributeType.number_type
n.check_type(1.0)
n.check_type(None)
self.assertRaises(TypeError, n.check_type, [])
self.assertRaises(TypeError, n.check_type, {})
self.assertRaises(TypeError, n.check_type, "foo")
self.assertRaises(TypeError, n.check_type, True)
self.assertRaises(TypeError, set_object_val)
self.assertRaises(TypeError, set_list_val)
def test_attribute_type_bool(self):
b = attribute.AttributeType.boolean_type
b.check_type(True)
b.check_type(None)
self.assertRaises(TypeError, b.check_type, 1)
self.assertRaises(TypeError, b.check_type, [])
self.assertRaises(TypeError, b.check_type, {})
self.assertRaises(TypeError, b.check_type, "foo")
def test_attribute_type_object(self):
o = attribute.AttributeType.object_type
o.check_type(None)
o.check_type(1)
o.check_type([])
o.check_type({})
o.check_type("foo")
o.check_type(True)
class TestAttributeCollection(base.TestCase):
@@ -324,7 +352,7 @@ class TestCoreOCCIResource(base.TestCase):
def test_mixins(self):
m = mixin.Mixin(None, None, None)
r = resource.Resource(None, [m], [])
r = resource.Resource(None, [m])
self.assertIsInstance(r.kind, kind.Kind)
self.assertEqual([m], r.mixins)