def validate(value): """Validate the input :param value: A event dict :returns: value :raises: Invalid if event not in proper format """ atypes.DictType(str, str).validate(value) keys = set(value) # Check all mandatory fields are present missing = EventType.mandatory_fields.difference(keys) if missing: raise exception.Invalid( _('Missing mandatory keys: %s') % ', '.join(missing)) # Check event is a supported event if value['event'] not in EventType.valid_events: raise exception.Invalid( _('%(event)s is not one of valid events: %(valid_events)s.') % { 'event': value['event'], 'valid_events': ', '.join(EventType.valid_events) }) return EventType.event_validators[value['event']](value)
def test_render_dict(self): self.assertEqual( json.dumps({'one': 'a', 'two': 'b', 'three': 'c'}), self.renderer.render('/', { 'result': {'one': 'a', 'two': 'b', 'three': 'c'}, 'datatype': atypes.DictType(str, str) }) )
def test_parse(self): # source as bytes s = b'{"o": {"id": 1234, "name": "an object"}}' # test bodyarg=True n = args.parse(s, {"o": NestedObj}, True)['o'] self.assertEqual(1234, n.o.id) self.assertEqual('an object', n.o.name) # source as file s = io.StringIO('{"o": {"id": 1234, "name": "an object"}}') # test bodyarg=False n = args.parse(s, {"o": Obj}, False)['o'] self.assertEqual(1234, n.id) self.assertEqual('an object', n.name) # fromjson ValueError s = '{"o": ["id", "name"]}' self.assertRaises(exception.InvalidInput, args.parse, s, {"o": atypes.DictType(str, str)}, False) s = '["id", "name"]' self.assertRaises(exception.InvalidInput, args.parse, s, {"o": atypes.DictType(str, str)}, True) # fromjson UnknownAttribute s = '{"o": {"foo": "bar", "id": 1234, "name": "an object"}}' self.assertRaises(exception.UnknownAttribute, args.parse, s, {"o": NestedObj}, True) self.assertRaises(exception.UnknownAttribute, args.parse, s, {"o": Obj}, False) # invalid json s = '{Sunn O)))}' self.assertRaises(exception.ClientSideError, args.parse, s, {"o": Obj}, False) # extra args s = '{"foo": "bar", "o": {"id": 1234, "name": "an object"}}' self.assertRaises(exception.UnknownArgument, args.parse, s, {"o": Obj}, False)
def validate_for_smart_nic(value): """Validates Smart NIC field are present 'port_id' and 'hostname' :param value: local link information of type Dictionary. :return: True if both fields 'port_id' and 'hostname' are present in 'value', False otherwise. """ atypes.DictType(str, str).validate(value) keys = set(value) if LocalLinkConnectionType.smart_nic_mandatory_fields <= keys: return True return False
def test_fromjson_dict(self): dtype = atypes.DictType(str, int) self.assertEqual({ 'zero': 0, 'one': 1, 'etc': 1234, 'none': None }, args.fromjson_dict(dtype, { 'zero': 0, 'one': '1', 'etc': '1_234', 'none': None })) self.assertRaises(ValueError, args.fromjson_dict, dtype, []) self.assertRaises(ValueError, args.fromjson_dict, dtype, {'one': 'one'})
def test_dict_sample(self): s = types.DictType(str, str).sample() assert isinstance(s, dict) assert s assert s == {'': ''}
def test_fromjson(self): # parse None self.assertIsNone(args.fromjson(None, None)) # parse array atype = atypes.ArrayType(int) self.assertEqual([0, 1, 1234, None], args.fromjson(atype, [0, '1', '1_234', None])) # parse dict dtype = atypes.DictType(str, int) self.assertEqual({ 'zero': 0, 'one': 1, 'etc': 1234, 'none': None }, args.fromjson(dtype, { 'zero': 0, 'one': '1', 'etc': '1_234', 'none': None })) # parse bytes self.assertEqual(b'asdf', args.fromjson(bytes, b'asdf')) self.assertEqual(b'asdf', args.fromjson(bytes, 'asdf')) self.assertEqual(b'33', args.fromjson(bytes, 33)) self.assertEqual(b'3.14', args.fromjson(bytes, 3.14)) # parse str self.assertEqual('asdf', args.fromjson(str, b'asdf')) self.assertEqual('asdf', args.fromjson(str, 'asdf')) # parse int/float self.assertEqual(3, args.fromjson(int, '3')) self.assertEqual(3, args.fromjson(int, 3)) self.assertEqual(3.14, args.fromjson(float, 3.14)) # parse bool self.assertFalse(args.fromjson(bool, 'no')) self.assertTrue(args.fromjson(bool, 'yes')) # parse decimal self.assertEqual(decimal.Decimal(3.14), args.fromjson(decimal.Decimal, 3.14)) # parse datetime expected = datetime.datetime(2015, 8, 13, 11, 38, 9, 496475) self.assertEqual( expected, args.fromjson(datetime.datetime, '2015-08-13T11:38:09.496475')) # parse complex n = args.fromjson(NestedObj, {'o': {'id': 1234, 'name': 'an object'}}) self.assertIsInstance(n.o, Obj) self.assertEqual(1234, n.o.id) self.assertEqual('an object', n.o.name) self.assertEqual('foo', n.o.default_field) # parse usertype self.assertEqual(['0', '1', '2', 'three'], args.fromjson(types.listtype, '0,1, 2, three'))
def validate(value): """Validate and convert the input to a LocalLinkConnectionType. :param value: A dictionary of values to validate, switch_id is a MAC address or an OpenFlow based datapath_id, switch_info is an optional field. Required Smart NIC fields are port_id and hostname. For example:: { 'switch_id': mac_or_datapath_id(), 'port_id': 'Ethernet3/1', 'switch_info': 'switch1' } Or for Smart NIC:: { 'port_id': 'rep0-0', 'hostname': 'host1-bf' } :returns: A dictionary. :raises: Invalid if some of the keys in the dictionary being validated are unknown, invalid, or some required ones are missing. """ atypes.DictType(str, str).validate(value) keys = set(value) # This is to workaround an issue when an API object is initialized from # RPC object, in which dictionary fields that are set to None become # empty dictionaries if not keys: return value invalid = keys - LocalLinkConnectionType.valid_fields if invalid: raise exception.Invalid(_('%s are invalid keys') % (invalid)) # If network_type is 'unmanaged', this is a network with no switch # management. i.e local_link_connection details are not required. if 'network_type' in keys: if (value['network_type'] not in LocalLinkConnectionType.valid_network_types): msg = _( 'Invalid network_type %(type)s, valid network_types are ' '%(valid_network_types)s.') % { 'type': value['network_type'], 'valid_network_types': LocalLinkConnectionType.valid_network_types } raise exception.Invalid(msg) if (value['network_type'] == 'unmanaged' and not (keys - {'network_type'})): # Only valid network_type 'unmanaged' is set, no for further # validation required. return value # Check any mandatory fields sets are present for mandatory_set in LocalLinkConnectionType.mandatory_fields_list: if mandatory_set <= keys: break else: msg = _('Missing mandatory keys. Required keys are ' '%(required_fields)s. Or in case of Smart NIC ' '%(smart_nic_required_fields)s. ' 'Submitted keys are %(keys)s .') % { 'required_fields': LocalLinkConnectionType.local_link_mandatory_fields, 'smart_nic_required_fields': LocalLinkConnectionType.smart_nic_mandatory_fields, 'keys': keys } raise exception.Invalid(msg) # Check switch_id is either a valid mac address or # OpenFlow datapath_id and normalize it. try: value['switch_id'] = utils.validate_and_normalize_mac( value['switch_id']) except exception.InvalidMAC: try: value['switch_id'] = utils.validate_and_normalize_datapath_id( value['switch_id']) except exception.InvalidDatapathID: raise exception.InvalidSwitchID(switch_id=value['switch_id']) except KeyError: # In Smart NIC case 'switch_id' is optional. pass return value