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 <yamam...@valinux.co.jp> > --- > 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 > Ryu-devel@lists.sourceforge.net > 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 Ryu-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ryu-devel