papi: fix default handling
The BaseTypers object were reused, so a default for anyother mesage would be inherited in new messages. Type: fix Fixes: 85465588b18fef9c4712f864f512e00741e2d4f2 Change-Id: Ie1efb85a76b088653eb9ea4b88540c98b6b0aad0 Signed-off-by: Ole Troan <ot@cisco.com> (cherry picked from commit 40dc4b35e3d946efbc5c2b8b0af5e52d67b7fe6c)
This commit is contained in:

committed by
Andrew Yourtchenko

parent
48ec77e84e
commit
3584f0936c
@ -66,14 +66,43 @@ class TestDefaults(unittest.TestCase):
|
||||
def test_defaults(self):
|
||||
default_type = VPPType('default_type_t',
|
||||
[['u16', 'mtu', {'default': 1500, 'limit': 0}]])
|
||||
without_default_type = VPPType('without_default_type_t',
|
||||
[['u16', 'mtu']])
|
||||
|
||||
b = default_type.pack({})
|
||||
self.assertEqual(len(b), 2)
|
||||
|
||||
nt, size = default_type.unpack(b)
|
||||
self.assertEqual(len(b), size)
|
||||
self.assertEqual(nt.mtu, 1500)
|
||||
|
||||
# distinguish between parameter 0 and parameter not passed
|
||||
b = default_type.pack({'mtu': 0})
|
||||
self.assertEqual(len(b), 2)
|
||||
nt, size = default_type.unpack(b)
|
||||
self.assertEqual(len(b), size)
|
||||
self.assertEqual(nt.mtu, 0)
|
||||
|
||||
# Ensure that basetypes does not inherit default
|
||||
b = without_default_type.pack({})
|
||||
self.assertEqual(len(b), 2)
|
||||
nt, size = default_type.unpack(b)
|
||||
self.assertEqual(len(b), size)
|
||||
self.assertEqual(nt.mtu, 0)
|
||||
|
||||
# default enum type
|
||||
VPPEnumType('vl_api_enum_t', [["ADDRESS_IP4", 0],
|
||||
["ADDRESS_IP6", 1],
|
||||
{"enumtype": "u32"}])
|
||||
|
||||
default_with_enum = VPPType('default_enum_type_t',
|
||||
[['u16', 'mtu'], ['vl_api_enum_t',
|
||||
'e', {'default': 1}]])
|
||||
|
||||
b = default_with_enum.pack({})
|
||||
self.assertEqual(len(b), 6)
|
||||
nt, size = default_with_enum.unpack(b)
|
||||
self.assertEqual(len(b), size)
|
||||
self.assertEqual(nt.e, 1)
|
||||
|
||||
class TestAddType(unittest.TestCase):
|
||||
|
||||
|
@ -88,12 +88,8 @@ class BaseTypes(object):
|
||||
self.size = self.packer.size
|
||||
self.options = options
|
||||
|
||||
def __call__(self, args):
|
||||
self.options = args
|
||||
return self
|
||||
|
||||
def pack(self, data, kwargs=None):
|
||||
if not data: # Default to zero if not specified
|
||||
if data is None: # Default to zero if not specified
|
||||
if self.options and 'default' in self.options:
|
||||
data = self.options['default']
|
||||
else:
|
||||
@ -152,6 +148,7 @@ types = {'u8': BaseTypes('u8'), 'u16': BaseTypes('u16'),
|
||||
'u64': BaseTypes('u64'), 'f64': BaseTypes('f64'),
|
||||
'bool': BaseTypes('bool'), 'string': String}
|
||||
|
||||
class_types = {}
|
||||
|
||||
def vpp_get_type(name):
|
||||
try:
|
||||
@ -172,10 +169,6 @@ class FixedList_u8(object):
|
||||
self.size = self.packer.size
|
||||
self.field_type = field_type
|
||||
|
||||
def __call__(self, args):
|
||||
self.options = args
|
||||
return self
|
||||
|
||||
def pack(self, data, kwargs=None):
|
||||
"""Packs a fixed length bytestring. Left-pads with zeros
|
||||
if input data is too short."""
|
||||
@ -207,10 +200,6 @@ class FixedList(object):
|
||||
self.name = name
|
||||
self.field_type = field_type
|
||||
|
||||
def __call__(self, args):
|
||||
self.options = args
|
||||
return self
|
||||
|
||||
def pack(self, list, kwargs):
|
||||
if len(list) != self.num:
|
||||
raise VPPSerializerValueError(
|
||||
@ -289,10 +278,6 @@ class VLAList_legacy():
|
||||
self.packer = types[field_type]
|
||||
self.size = self.packer.size
|
||||
|
||||
def __call__(self, args):
|
||||
self.options = args
|
||||
return self
|
||||
|
||||
def pack(self, list, kwargs=None):
|
||||
if self.packer.size == 1:
|
||||
return bytes(list)
|
||||
@ -319,9 +304,11 @@ class VLAList_legacy():
|
||||
|
||||
|
||||
class VPPEnumType(object):
|
||||
def __init__(self, name, msgdef):
|
||||
def __init__(self, name, msgdef, options=None):
|
||||
self.size = types['u32'].size
|
||||
self.name = name
|
||||
self.enumtype = 'u32'
|
||||
self.msgdef = msgdef
|
||||
e_hash = {}
|
||||
for f in msgdef:
|
||||
if type(f) is dict and 'enumtype' in f:
|
||||
@ -333,10 +320,8 @@ class VPPEnumType(object):
|
||||
e_hash[ename] = evalue
|
||||
self.enum = IntFlag(name, e_hash)
|
||||
types[name] = self
|
||||
|
||||
def __call__(self, args):
|
||||
self.options = args
|
||||
return self
|
||||
class_types[name] = VPPEnumType
|
||||
self.options = options
|
||||
|
||||
def __getattr__(self, name):
|
||||
return self.enum[name]
|
||||
@ -348,6 +333,12 @@ class VPPEnumType(object):
|
||||
__nonzero__ = __bool__
|
||||
|
||||
def pack(self, data, kwargs=None):
|
||||
if data is None: # Default to zero if not specified
|
||||
if self.options and 'default' in self.options:
|
||||
data = self.options['default']
|
||||
else:
|
||||
data = 0
|
||||
|
||||
return types[self.enumtype].pack(data)
|
||||
|
||||
def unpack(self, data, offset=0, result=None, ntc=False):
|
||||
@ -381,10 +372,6 @@ class VPPUnionType(object):
|
||||
types[name] = self
|
||||
self.tuple = collections.namedtuple(name, fields, rename=True)
|
||||
|
||||
def __call__(self, args):
|
||||
self.options = args
|
||||
return self
|
||||
|
||||
# Union of variable length?
|
||||
def pack(self, data, kwargs=None):
|
||||
if not data:
|
||||
@ -431,10 +418,6 @@ class VPPTypeAlias(object):
|
||||
types[name] = self
|
||||
self.toplevelconversion = False
|
||||
|
||||
def __call__(self, args):
|
||||
self.options = args
|
||||
return self
|
||||
|
||||
def pack(self, data, kwargs=None):
|
||||
if data and conversion_required(data, self.name):
|
||||
try:
|
||||
@ -512,7 +495,14 @@ class VPPType(object):
|
||||
p = VLAList(f_name, f_type, f[3], length_index)
|
||||
self.packers.append(p)
|
||||
else:
|
||||
p = types[f_type](self.options)
|
||||
# Support default for basetypes and enums
|
||||
if 'default' in self.options:
|
||||
try:
|
||||
p = BaseTypes(f_type, 0, self.options)
|
||||
except KeyError:
|
||||
p = class_types[f_type](f_name, types[f_type].msgdef, self.options)
|
||||
else:
|
||||
p = types[f_type]
|
||||
self.packers.append(p)
|
||||
size += p.size
|
||||
|
||||
@ -521,10 +511,6 @@ class VPPType(object):
|
||||
types[name] = self
|
||||
self.toplevelconversion = False
|
||||
|
||||
def __call__(self, args):
|
||||
self.options = args
|
||||
return self
|
||||
|
||||
def pack(self, data, kwargs=None):
|
||||
if not kwargs:
|
||||
kwargs = data
|
||||
|
Reference in New Issue
Block a user