blob: 26f5937c4f150ab3e1b0958a2abd23964ed5eee8 [file] [log] [blame]
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#
#pylint: disable=wildcard-import,missing-docstring,too-many-public-methods
import unittest, json
from qpid_dispatch_internal.management.schema import Schema, BooleanType, EnumType, AttributeType, ValidationError, EnumValue, EntityType
from qpid_dispatch_internal.compat import OrderedDict
import collections
def replace_od(thing):
"""Replace OrderedDict with dict"""
if isinstance(thing, OrderedDict):
return dict((k, replace_od(v)) for k,v in thing.iteritems())
if isinstance(thing, list):
return [replace_od(t) for t in thing]
return thing
SCHEMA_1 = {
"prefix":"org.example",
"annotations": {
"entityId": {
"attributes": {
"name": {"type":"string", "required": True, "unique":True},
"type": {"type":"string", "required": True}
}
}
},
"entityTypes": {
"container": {
"singleton": True,
"annotations" : ["entityId"],
"attributes": {
"workerThreads" : {"type":"integer", "default": 1}
}
},
"listener": {
"annotations" : ["entityId"],
"attributes": {
"addr" : {"type":"string"}
}
},
"connector": {
"annotations" : ["entityId"],
"attributes": {
"addr" : {"type":"string"}
}
}
}
}
class SchemaTest(unittest.TestCase):
def test_bool(self):
b = BooleanType()
self.assertTrue(b.validate('on'))
self.assertTrue(b.validate(True))
self.assertFalse(b.validate(False))
self.assertFalse(b.validate('no'))
self.assertRaises(ValidationError, b.validate, 'x')
def test_enum(self):
e = EnumType(['a', 'b', 'c'])
self.assertEqual(e.validate('a'), 'a')
self.assertEqual(e.validate(1), 'b')
self.assertEqual(e.validate('c'), 2)
self.assertEqual(e.validate(2), 2)
self.assertRaises(ValidationError, e.validate, 'foo')
self.assertRaises(ValidationError, e.validate, 3)
self.assertEqual('["x"]', json.dumps([EnumValue('x',3)]))
def test_attribute_def(self):
a = AttributeType('foo', 'string', default='FOO')
self.assertEqual('FOO', a.missing_value())
self.assertEqual(a.validate('x'), 'x')
a = AttributeType('foo', 'string', default='FOO', required=True)
self.assertEqual('FOO', a.missing_value())
a = AttributeType('foo', 'string', required=True)
self.assertRaises(ValidationError, a.missing_value) # Missing required value.
a = AttributeType('foo', 'string', value='FOO') # Fixed value
self.assertEqual('FOO', a.missing_value())
self.assertEqual(a.validate('FOO'), 'FOO')
self.assertRaises(ValidationError, a.validate, 'XXX') # Bad fixed value
self.assertRaises(ValidationError, AttributeType, 'foo', 'string', value='FOO', default='BAR') # Illegal
a = AttributeType('foo', 'integer')
self.assertEqual(3, a.validate(3))
self.assertEqual(3, a.validate('3'))
self.assertEqual(3, a.validate(3.0))
self.assertRaises(ValidationError, a.validate, None)
self.assertRaises(ValidationError, a.validate, "xxx")
def test_entity_type(self):
s = Schema(annotations={
'i1':{'attributes': { 'foo1': {'type':'string', 'default':'FOO1'}}},
'i2':{'attributes': { 'foo2': {'type':'string', 'default':'FOO2'}}}})
e = EntityType('MyEntity', s, attributes={
'foo': {'type':'string', 'default':'FOO'},
'req': {'type':'integer', 'required':True},
'e': {'type':['x', 'y']}})
e.init()
self.assertRaises(ValidationError, e.validate, {}) # Missing required 'req'
self.assertEqual(e.validate({'req':42}), {'foo': 'FOO', 'req': 42})
# Try with an annotation
e = EntityType('e2', s, attributes={'x':{'type':'integer'}}, annotations=['i1', 'i2'])
e.init()
self.assertEqual(e.validate({'x':1}), {'x':1, 'foo1': 'FOO1', 'foo2': 'FOO2'})
def test_entity_refs(self):
e = EntityType('MyEntity', Schema(), attributes={
'type': {'type': 'string', 'required': True, 'value': '$$entityType'},
'name': {'type':'string', 'default':'$identity'},
'identity': {'type':'string', 'default':'$name', "required": True}})
self.assertEqual({'type': 'MyEntity', 'identity': 'x', 'name': 'x'},
e.validate({'identity':'x'}))
self.assertEqual({'type': 'MyEntity', 'identity': 'x', 'name': 'x'},
e.validate({'name':'x'}))
self.assertEqual({'type': 'MyEntity', 'identity': 'x', 'name': 'y'},
e.validate({'identity': 'x', 'name':'y'}))
self.assertRaises(ValidationError, e.validate, {}) # Circular reference.
def test_entity_annotation_refs(self):
s = Schema(annotations={
'i1': {'attributes': {
'name': {'type':'string', 'default':'$identity'},
'identity': {'type':'string', 'default':'$name', "required": True}}}})
e = EntityType('MyEntity', s, attributes={}, annotations=['i1'])
e.init()
self.assertEqual({'identity': 'x', 'name': 'x'}, e.validate({'identity':'x'}))
self.assertEqual({'identity': 'x', 'name': 'x'}, e.validate({'name':'x'}))
self.assertEqual({'identity': 'x', 'name': 'y'}, e.validate({'identity': 'x', 'name':'y'}))
self.assertRaises(ValidationError, e.validate, {})
def test_schema_validate(self):
s = Schema(**SCHEMA_1)
# Duplicate unique attribute 'name'
m = [{'type': 'listener', 'name':'x'},
{'type': 'listener', 'name':'x'}]
self.assertRaises(ValidationError, s.validate_all, m)
# Duplicate singleton entity 'container'
m = [{'type': 'container', 'name':'x'},
{'type': 'container', 'name':'y'}]
self.assertRaises(ValidationError, s.validate_all, m)
# Valid model
m = [{'type': 'container', 'name':'x'},
{'type': 'listener', 'name':'y'}]
s.validate_all(m)
def test_schema_entity(self):
s = Schema(**SCHEMA_1)
self.assertRaises(ValidationError, s.entity, {'type': 'nosuch'})
self.assertRaises(ValidationError, s.entity, {'type': 'listener', 'nosuch': 'x'})
e = s.entity({'type': 'listener', 'name':'x', 'addr':'foo'})
self.assertEqual(e.attributes, {'type': 'org.example.listener', 'name':'x', 'addr':'foo'})
self.assertEqual(e['addr'], 'foo')
self.assertRaises(ValidationError, e.__setitem__, 'nosuch', 'x')
try:
e.nosuch = 'x'
self.fail("Expected exception")
except: pass
if __name__ == '__main__':
unittest.main()