On Fri, May 10, 2013 at 03:01:13PM +0900, YAMAMOTO Takashi wrote:
> instead of explicit listing of of-wire attributes, use a heuristics
> to exclude internal attributes. (eg. buf, datapath, etc)
>
> this commit changes __str__ outputs. update a test case accordingly.
>
> Signed-off-by: YAMAMOTO Takashi <[email protected]>
> ---
> ryu/ofproto/ofproto_parser.py | 27 +++++++++++++++++++++++----
> ryu/ofproto/ofproto_v1_0_parser.py | 18 ------------------
> ryu/tests/unit/ofproto/test_parser_v10.py | 13 ++++++++++---
> 3 files changed, 33 insertions(+), 25 deletions(-)
>
> diff --git a/ryu/ofproto/ofproto_parser.py b/ryu/ofproto/ofproto_parser.py
> index 26adead..5b4cf24 100644
> --- a/ryu/ofproto/ofproto_parser.py
> +++ b/ryu/ofproto/ofproto_parser.py
> @@ -16,6 +16,7 @@
>
> import logging
> import struct
> +import functools
>
> from ryu import exception
>
> @@ -50,7 +51,17 @@ def msg(datapath, version, msg_type, msg_len, xid, buf):
> return msg_parser(datapath, version, msg_type, msg_len, xid, buf)
>
>
> +def create_list_of_attributes(f):
> + @functools.wraps(f)
> + def wrapper(self, *args, **kwargs):
> + ret = f(self, *args, **kwargs)
> + self._attributes = set(dir(self))
> + return ret
> + return wrapper
> +
> +
> class MsgBase(object):
> + @create_list_of_attributes
> def __init__(self, datapath):
> self.datapath = datapath
> self.version = None
> @@ -75,9 +86,10 @@ class MsgBase(object):
> self.buf = buffer(buf)
>
> def __str__(self):
> - return 'version: 0x%x msg_type 0x%x xid 0x%x' % (self.version,
> - self.msg_type,
> - self.xid)
> + buf = 'version: 0x%x msg_type 0x%x xid 0x%x' % (self.version,
> + self.msg_type,
> + self.xid)
> + return msg_str_attr(self, buf)
>
> @classmethod
> def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
> @@ -135,7 +147,14 @@ def msg_pack_into(fmt, buf, offset, *args):
> struct.pack_into(fmt, buf, offset, *args)
>
>
> -def msg_str_attr(msg, buf, attr_list):
> +def msg_str_attr(msg, buf, attr_list=None):
> + if attr_list is None:
> + exclude = ['_attributes']
> + try:
> + exclude += msg._attributes
> + except AttributeError:
> + pass
> + attr_list = set(dir(msg)) - set(exclude)
Clever trick.
Is the result of str(msg) non-deterministic depending on the internal hash?
thanks,
> for attr in attr_list:
> val = getattr(msg, attr, None)
> if val is not None:
> diff --git a/ryu/ofproto/ofproto_v1_0_parser.py
> b/ryu/ofproto/ofproto_v1_0_parser.py
> index 7081c31..46a6cc0 100644
> --- a/ryu/ofproto/ofproto_v1_0_parser.py
> +++ b/ryu/ofproto/ofproto_v1_0_parser.py
> @@ -1620,12 +1620,6 @@ class OFPSwitchFeatures(MsgBase):
> def __init__(self, datapath):
> super(OFPSwitchFeatures, self).__init__(datapath)
>
> - def __str__(self):
> - buf = super(OFPSwitchFeatures, self).__str__() + ' port'
> - for _port_no, p in getattr(self, 'ports', {}).items():
> - buf += ' ' + str(p)
> - return buf
> -
> @classmethod
> def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
> msg = super(OFPSwitchFeatures, cls).parser(datapath, version,
> msg_type,
> @@ -1675,11 +1669,6 @@ class OFPPacketIn(MsgBase):
> def __init__(self, datapath):
> super(OFPPacketIn, self).__init__(datapath)
>
> - def __str__(self):
> - buf = super(OFPPacketIn, self).__str__()
> - return msg_str_attr(self, buf,
> - ('buffer_id', 'total_len', 'in_port', 'reason'))
> -
> @classmethod
> def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
> msg = super(OFPPacketIn, cls).parser(datapath, version, msg_type,
> @@ -1726,13 +1715,6 @@ class OFPFlowRemoved(MsgBase):
> def __init__(self, datapath):
> super(OFPFlowRemoved, self).__init__(datapath)
>
> - def __str__(self):
> - buf = super(OFPFlowRemoved, self).__str__()
> - return msg_str_attr(self, buf,
> - ('match', 'cookie', 'priority', 'reason',
> - 'duration_sec', 'duration_nsec',
> - 'idle_timeout', 'packet_count', 'byte_count'))
> -
> @classmethod
> def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
> msg = super(OFPFlowRemoved, cls).parser(datapath, version, msg_type,
> diff --git a/ryu/tests/unit/ofproto/test_parser_v10.py
> b/ryu/tests/unit/ofproto/test_parser_v10.py
> index 8723231..d4184c1 100644
> --- a/ryu/tests/unit/ofproto/test_parser_v10.py
> +++ b/ryu/tests/unit/ofproto/test_parser_v10.py
> @@ -3560,7 +3560,11 @@ class TestOFPSwitchFeatures(unittest.TestCase):
> eq_(peer['val'], port.peer)
>
> # test __str__()
> - list_ = ('version:', 'msg_type', 'xid', 'port')
> + #
> + # an example:
> + # switch features ev version: 0x1 msg_type 0x6 xid 0x73a92862
> datapath_id 8 n_tables 2 capabilities 0 actions 2047 ports {1:
> OFPPhyPort(port_no=1, hw_addr='\x1a\xc1Q\xff\xef\x8a',
> name='veth1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', config=0, state=0,
> curr=192, advertised=0, supported=0, peer=0), 2: OFPPhyPort(port_no=2,
> hw_addr='\xce/\xa2\x87\xf6p',
> name='veth3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', config=0, state=0,
> curr=192, advertised=0, supported=0, peer=0), 3: OFPPhyPort(port_no=3,
> hw_addr='\xca\x8a\x1e\xf3w\xef',
> name='veth5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', config=0, state=0,
> curr=192, advertised=0, supported=0, peer=0), 4: OFPPhyPort(port_no=4,
> hw_addr='\xfa\xbcw\x8d~\x0b',
> name='veth7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', config=0, state=0,
> curr=192, advertised=0, supported=0, peer=0)} n_buffers 256
> +
> + list_ = ('version:', 'msg_type', 'xid', 'ports')
> check = {}
> str_ = str(res)
> str_ = str_.rsplit()
> @@ -3568,13 +3572,16 @@ class TestOFPSwitchFeatures(unittest.TestCase):
> i = 0
> for s in str_:
> if s in list_:
> - check[str_[i]] = str_[i + 1]
> + if str_[i + 1].startswith('{'): # "{1: OFPPhyPort..."
> + check[str_[i]] = str_[i + 2]
> + else:
> + check[str_[i]] = str_[i + 1]
> i += 1
>
> eq_(hex(version['val']).find(check['version:']), 0)
> eq_(hex(msg_type['val']).find(check['msg_type']), 0)
> eq_(hex(xid['val']).find(check['xid']), 0)
> - eq_(check['port'].find('OFPPhyPort'), 0)
> + eq_(check['ports'].find('OFPPhyPort'), 0)
>
> def test_serialize(self):
> # Not used.
> --
> 1.8.0.1
>
>
> ------------------------------------------------------------------------------
> Learn Graph Databases - Download FREE O'Reilly Book
> "Graph Databases" is the definitive new guide to graph databases and
> their applications. This 200-page book is written by three acclaimed
> leaders in the field. The early access version is available now.
> Download your free book today! http://p.sf.net/sfu/neotech_d2d_may
> _______________________________________________
> Ryu-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/ryu-devel
>
--
yamahata
------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and
their applications. This 200-page book is written by three acclaimed
leaders in the field. The early access version is available now.
Download your free book today! http://p.sf.net/sfu/neotech_d2d_may
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel