pyloxi: parse unknown subclasses as the superclass
Previously we would throw an exception if we encountered a (for example)
experimenter action subclass that we didn't know existed. This was fine for
OFTest but causes problems for other tools that use pyloxi.
This change generates a full set of pack/unpack/pretty_print functions for
virtual classes. If a discriminator field contains a subtype we don't know
about, the virtual class is instantiated instead.
This also removes the special cases around unknown hello elements.
diff --git a/py_gen/tests/of10.py b/py_gen/tests/of10.py
index 250000f..7e10335 100644
--- a/py_gen/tests/of10.py
+++ b/py_gen/tests/of10.py
@@ -112,10 +112,10 @@
with self.assertRaisesRegexp(ofp.ProtocolError, 'Buffer too short'):
loxi.generic_util.unpack_list(OFReader(buf), ofp.action.action.unpack)
- def test_invalid_action_type(self):
+ def test_unknown_action_type(self):
buf = '\xff\xfe\x00\x08\x00\x00\x00\x00'
- with self.assertRaisesRegexp(ofp.ProtocolError, 'unknown action subtype'):
- loxi.generic_util.unpack_list(OFReader(buf), ofp.action.action.unpack)
+ result = loxi.generic_util.unpack_list(OFReader(buf), ofp.action.action.unpack)
+ self.assertEquals(result, [ofp.action.action(type=0xfffe)])
class TestConstants(unittest.TestCase):
def test_ports(self):
@@ -200,11 +200,19 @@
test_klasses = [x for x in ofp.message.__dict__.values()
if type(x) == type
and issubclass(x, ofp.message.message)
- and hasattr(x, 'pack')]
+ and not hasattr(x, 'subtypes')]
for klass in test_klasses:
self.assertIsInstance(ofp.message.parse_message(klass(xid=1).pack()), klass)
+ def test_parse_unknown_message(self):
+ import loxi
+ import loxi.of10 as ofp
+
+ buf = "\x01\xfe\x00\x08\x12\x34\x56\x78"
+ msg = ofp.message.parse_message(buf)
+ self.assertIsInstance(msg, ofp.message.message)
+
class TestUtils(unittest.TestCase):
def test_pretty_wildcards(self):
self.assertEquals("OFPFW_ALL", ofp.util.pretty_wildcards(ofp.OFPFW_ALL))
@@ -231,7 +239,7 @@
for klass in mod.__dict__.values()
if isinstance(klass, type) and
issubclass(klass, loxi.OFObject) and
- hasattr(klass, 'pack')]
+ not hasattr(klass, 'subtypes')]
self.klasses.sort(key=lambda x: str(x))
def test_serialization(self):
diff --git a/py_gen/tests/of11.py b/py_gen/tests/of11.py
index d620509..7ae6d8a 100644
--- a/py_gen/tests/of11.py
+++ b/py_gen/tests/of11.py
@@ -69,7 +69,7 @@
for klass in mod.__dict__.values()
if isinstance(klass, type) and
issubclass(klass, loxi.OFObject) and
- hasattr(klass, 'pack')]
+ not hasattr(klass, 'subtypes')]
self.klasses.sort(key=lambda x: str(x))
def test_serialization(self):
diff --git a/py_gen/tests/of12.py b/py_gen/tests/of12.py
index 4774672..c463c50 100644
--- a/py_gen/tests/of12.py
+++ b/py_gen/tests/of12.py
@@ -78,7 +78,7 @@
for klass in mod.__dict__.values()
if isinstance(klass, type) and
issubclass(klass, loxi.OFObject) and
- hasattr(klass, 'pack')]
+ not hasattr(klass, 'subtypes')]
self.klasses.sort(key=lambda x: str(x))
def test_serialization(self):
diff --git a/py_gen/tests/of13.py b/py_gen/tests/of13.py
index 8e258df..c5a16b2 100644
--- a/py_gen/tests/of13.py
+++ b/py_gen/tests/of13.py
@@ -60,18 +60,6 @@
self.assertTrue(hasattr(loxi.of13, "message"))
self.assertTrue(hasattr(loxi.of13, "oxm"))
-class TestCommon(unittest.TestCase):
- def test_list_hello_elem_unpack(self):
- buf = ''.join([
- '\x00\x01\x00\x04', # versionbitmap
- '\x00\x00\x00\x04', # unknown type
- '\x00\x01\x00\x04', # versionbitmap
- ])
- l = ofp.util.unpack_list_hello_elem(OFReader(buf))
- self.assertEquals(len(l), 2)
- self.assertTrue(isinstance(l[0], ofp.hello_elem_versionbitmap))
- self.assertTrue(isinstance(l[1], ofp.hello_elem_versionbitmap))
-
# The majority of the serialization tests are created here using the files in
# the test_data directory.
class TestDataFiles(unittest.TestCase):
@@ -91,7 +79,7 @@
for klass in mod.__dict__.values()
if isinstance(klass, type) and
issubclass(klass, loxi.OFObject) and
- hasattr(klass, 'pack')]
+ not hasattr(klass, 'subtypes')]
self.klasses.sort(key=lambda x: str(x))
def test_serialization(self):